home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / djgpp / src / gas-211 / gas / config / obj-coff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-30  |  70.9 KB  |  2,565 lines

  1. /* coff object file format
  2.    Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
  3.  
  4.    This file is part of GAS.
  5.  
  6.    GAS is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2, or (at your option)
  9.    any later version.
  10.  
  11.    GAS is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with GAS; see the file COPYING.  If not, write to
  18.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "as.h"
  21.  
  22. #include "obstack.h"
  23.  
  24. #ifndef BFD_ASSEMBLER
  25. lineno *lineno_rootP;
  26.  
  27. const short seg_N_TYPE[] =
  28. {                /* in: segT   out: N_TYPE bits */
  29.   C_ABS_SECTION,
  30.   C_TEXT_SECTION,
  31.   C_DATA_SECTION,
  32.   C_BSS_SECTION,
  33.   C_UNDEF_SECTION,        /* SEG_UNKNOWN */
  34.   C_UNDEF_SECTION,        /* SEG_ABSENT */
  35.   C_UNDEF_SECTION,        /* SEG_PASS1 */
  36.   C_UNDEF_SECTION,        /* SEG_GOOF */
  37.   C_UNDEF_SECTION,        /* SEG_BIG */
  38.   C_UNDEF_SECTION,        /* SEG_DIFFERENCE */
  39.   C_DEBUG_SECTION,        /* SEG_DEBUG */
  40.   C_NTV_SECTION,        /* SEG_NTV */
  41.   C_PTV_SECTION,        /* SEG_PTV */
  42.   C_REGISTER_SECTION,        /* SEG_REGISTER */
  43. };
  44.  
  45.  
  46. /* Add 4 to the real value to get the index and compensate the negatives */
  47.  
  48. const segT N_TYPE_seg[32] =
  49. {
  50.   SEG_PTV,            /* C_PTV_SECTION    == -4 */
  51.   SEG_NTV,            /* C_NTV_SECTION    == -3 */
  52.   SEG_DEBUG,            /* C_DEBUG_SECTION    == -2 */
  53.   SEG_ABSOLUTE,            /* C_ABS_SECTION    == -1 */
  54.   SEG_UNKNOWN,            /* C_UNDEF_SECTION    == 0 */
  55.   SEG_TEXT,            /* C_TEXT_SECTION    == 1 */
  56.   SEG_DATA,            /* C_DATA_SECTION    == 2 */
  57.   SEG_BSS,            /* C_BSS_SECTION    == 3 */
  58.   SEG_REGISTER,            /* C_REGISTER_SECTION   == 4 */
  59.   SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
  60.   SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
  61.   SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF
  62. };
  63. #endif
  64.  
  65. char *s_get_name PARAMS ((symbolS * s));
  66. static symbolS *tag_find_or_make PARAMS ((char *name));
  67. static symbolS *tag_find PARAMS ((char *name));
  68. #ifdef BFD_HEADERS
  69. static void obj_coff_section_header_append PARAMS ((char **where, struct internal_scnhdr * header));
  70. #else
  71. static void obj_coff_section_header_append PARAMS ((char **where, SCNHDR * header));
  72. #endif
  73. static void obj_coff_def PARAMS ((int what));
  74. static void obj_coff_dim PARAMS ((void));
  75. static void obj_coff_endef PARAMS ((void));
  76. static void obj_coff_line PARAMS ((void));
  77. static void obj_coff_ln PARAMS ((void));
  78. static void obj_coff_scl PARAMS ((void));
  79. static void obj_coff_size PARAMS ((void));
  80. static void obj_coff_stab PARAMS ((int what));
  81. static void obj_coff_tag PARAMS ((void));
  82. static void obj_coff_type PARAMS ((void));
  83. static void obj_coff_val PARAMS ((void));
  84. static void tag_init PARAMS ((void));
  85. static void tag_insert PARAMS ((char *name, symbolS * symbolP));
  86.  
  87. #ifdef BFD_ASSEMBLER
  88. static void SA_SET_SYM_ENDNDX PARAMS ((symbolS *, symbolS *));
  89. static void SA_SET_SYM_TAGNDX PARAMS ((symbolS *, symbolS *));
  90. #endif
  91.  
  92. int line_base;
  93.  
  94. static struct hash_control *tag_hash;
  95. static symbolS *def_symbol_in_progress;
  96.  
  97. const pseudo_typeS obj_pseudo_table[] =
  98. {
  99. #ifndef IGNORE_DEBUG
  100.   {"def", obj_coff_def, 0},
  101.   {"dim", obj_coff_dim, 0},
  102.   {"endef", obj_coff_endef, 0},
  103.   {"line", obj_coff_line, 0},
  104.   {"ln", obj_coff_ln, 0},
  105.   {"scl", obj_coff_scl, 0},
  106.   {"size", obj_coff_size, 0},
  107.   {"tag", obj_coff_tag, 0},
  108.   {"type", obj_coff_type, 0},
  109.   {"val", obj_coff_val, 0},
  110. #else
  111.   {"def", s_ignore, 0},
  112.   {"dim", s_ignore, 0},
  113.   {"endef", s_ignore, 0},
  114.   {"line", s_ignore, 0},
  115.   {"ln", s_ignore, 0},
  116.   {"scl", s_ignore, 0},
  117.   {"size", s_ignore, 0},
  118.   {"tag", s_ignore, 0},
  119.   {"type", s_ignore, 0},
  120.   {"val", s_ignore, 0},
  121. #endif /* ignore debug */
  122.  
  123.   {"ident", s_ignore, 0},    /* we don't yet handle this. */
  124.  
  125.  
  126.   /* stabs aka a.out aka b.out directives for debug symbols.
  127.      Currently ignored silently.  Except for .line at which
  128.      we guess from context. */
  129.   {"desc", s_ignore, 0},    /* def */
  130.   {"stabd", obj_coff_stab, 'd'},/* stabs */
  131.   {"stabn", obj_coff_stab, 'n'},/* stabs */
  132.   {"stabs", obj_coff_stab, 's'},/* stabs */
  133.  
  134.   /* stabs-in-coff (?) debug pseudos (ignored) */
  135.   {"optim", s_ignore, 0},    /* For sun386i cc (?) */
  136.   /* other stuff */
  137.   {"ABORT", s_abort, 0},
  138.  
  139.   {NULL}            /* end sentinel */
  140. };                /* obj_pseudo_table */
  141.  
  142. #ifdef BFD_ASSEMBLER
  143. struct line_no {
  144.   struct line_no *next;
  145.   fragS *frag;
  146.   alent l;
  147. };
  148. #endif
  149.  
  150. #define GET_FILENAME_STRING(X) \
  151. ((char*)(&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
  152.  
  153. /* obj dependant output values */
  154. #ifndef BFD_ASSEMBLER
  155. #ifdef BFD_HEADERS
  156. static struct internal_scnhdr bss_section_header;
  157. struct internal_scnhdr data_section_header;
  158. struct internal_scnhdr text_section_header;
  159. #else
  160. static SCNHDR bss_section_header;
  161. SCNHDR data_section_header;
  162. SCNHDR text_section_header;
  163. #endif
  164. #endif
  165.  
  166. #ifdef BFD_ASSEMBLER
  167.  
  168. /* @@ Ick.  */
  169. static segT
  170. fetch_coff_debug_section ()
  171. {
  172.   static segT debug_section;
  173.   if (!debug_section)
  174.     {
  175.       CONST asymbol *s;
  176.       s = bfd_make_debug_symbol (stdoutput, (char *) 0, 0);
  177.       assert (s != 0);
  178.       debug_section = s->section;
  179.     }
  180.   return debug_section;
  181. }
  182.  
  183. static void
  184. SA_SET_SYM_ENDNDX (sym, val)
  185.      symbolS *sym;
  186.      symbolS *val;
  187. {
  188.   combined_entry_type *entry, *p;
  189.  
  190.   entry = &coffsymbol (sym->bsym)->native[1];
  191.   p = coffsymbol (val->bsym)->native;
  192.   entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p;
  193.   entry->fix_end = 1;
  194. }
  195.  
  196. static void
  197. SA_SET_SYM_TAGNDX (sym, val)
  198.      symbolS *sym;
  199.      symbolS *val;
  200. {
  201.   combined_entry_type *entry, *p;
  202.  
  203.   entry = &coffsymbol (sym->bsym)->native[1];
  204.   p = coffsymbol (val->bsym)->native;
  205.   entry->u.auxent.x_sym.x_tagndx.p = p;
  206.   entry->fix_tag = 1;
  207. }
  208.  
  209. #else /* ! BFD_ASSEMBLER */
  210.  
  211. /* Relocation. */
  212.  
  213. static int
  214. reloc_compare (p1, p2)
  215. #ifdef BFD_HEADERS
  216.      struct internal_reloc *p1, *p2;
  217. #else
  218.      RELOC *p1, *p2;
  219. #endif
  220. {
  221.   return (int) (p1->r_vaddr - p2->r_vaddr);
  222. }
  223.  
  224. /*
  225.  *        emit_relocations()
  226.  *
  227.  * Crawl along a fixS chain. Emit the segment's relocations.
  228.  */
  229.  
  230. void
  231. obj_emit_relocations (where, fixP, segment_address_in_file)
  232.      char **where;
  233.      fixS *fixP;        /* Fixup chain for this segment. */
  234.      relax_addressT segment_address_in_file;
  235. {
  236. #ifdef BFD_HEADERS
  237.   struct internal_reloc *ri_table;
  238. #else
  239.   RELOC *ri_table;
  240. #endif
  241. #ifdef TC_I960
  242.   char *callj_table;
  243. #endif
  244.   symbolS *symbolP;
  245.   int i, count;
  246.   fixS *p;
  247.  
  248.   for (count = 0, p = fixP; p; p = p->fx_next)
  249.     if (p->fx_addsy)
  250.       count++;
  251.   if (!count)
  252.     return;
  253.  
  254. #ifdef BFD_HEADERS
  255.   ri_table = (struct internal_reloc *) calloc (sizeof (*ri_table), count);
  256. #else
  257.   ri_table = (RELOC *) calloc (sizeof (*ri_table), count);
  258. #endif
  259.   if (!ri_table)
  260.     as_fatal ("obj_emit_relocations: Could not malloc relocation table");
  261.  
  262. #ifdef TC_I960
  263.   callj_table = (char *) malloc (sizeof (char) * count);
  264.   if (!callj_table)
  265.     as_fatal ("obj_emit_relocations: Could not malloc callj table");
  266. #endif
  267.  
  268.   for (i = 0; fixP; fixP = fixP->fx_next)
  269.     {
  270.       if (symbolP = fixP->fx_addsy)
  271.     {
  272.       int rtype_ok = 0;
  273. #if defined(TC_M68K)
  274.       ri_table[i].r_type = (fixP->fx_pcrel ?
  275.                 (fixP->fx_size == 1 ? R_PCRBYTE :
  276.                  fixP->fx_size == 2 ? R_PCRWORD :
  277.                  R_PCRLONG) :
  278.                 (fixP->fx_size == 1 ? R_RELBYTE :
  279.                  fixP->fx_size == 2 ? R_RELWORD :
  280.                  R_RELLONG));
  281.       rtype_ok = 1;
  282. #endif
  283. #if defined(TC_I386)
  284.       /* FIXME-SOON R_OFF8 & R_DIR16 are a vague guess, completly
  285.                untested. */
  286.       ri_table[i].r_type = (fixP->fx_pcrel ?
  287.                 (fixP->fx_size == 1 ? R_PCRBYTE :
  288.                  fixP->fx_size == 2 ? R_PCRWORD :
  289.                  R_PCRLONG) :
  290.                 (fixP->fx_size == 1 ? R_OFF8 :
  291.                  fixP->fx_size == 2 ? R_DIR16 :
  292.                  R_DIR32));
  293.       rtype_ok = 1;
  294. #endif
  295. #if defined(TC_I960)
  296.       ri_table[i].r_type = (fixP->fx_pcrel
  297.                 ? R_IPRMED
  298.                 : R_RELLONG);
  299.       callj_table[i] = fixP->fx_callj ? 1 : 0;
  300.       rtype_ok = 1;
  301. #endif
  302. #if defined(TC_A29K)
  303.       ri_table[i].r_type = tc_coff_fix2rtype (fixP);
  304.       rtype_ok = 1;
  305. #endif
  306.       if (!rtype_ok)
  307.         abort ();
  308.       ri_table[i].r_vaddr = (fixP->fx_frag->fr_address
  309.                  + fixP->fx_where);
  310.       /* If symbol associated to relocation entry is a bss symbol
  311.          or undefined symbol just remember the index of the symbol.
  312.          Otherwise store the index of the symbol describing the
  313.          section the symbol belong to. This heuristic speeds up ld.
  314.          */
  315.       /* Local symbols can generate relocation information. In case
  316.          of structure return for instance. But they have no symbol
  317.          number because they won't be emitted in the final object.
  318.          In the case where they are in the BSS section, this leads
  319.          to an incorrect r_symndx.
  320.          Under bsd the loader do not care if the symbol reference
  321.          is incorrect. But the SYS V ld complains about this. To
  322.          avoid this we associate the symbol to the associated
  323.          section, *even* if it is the BSS section. */
  324.       /* If someone can tell me why the other symbols of the bss
  325.          section are not associated with the .bss section entry,
  326.          I'd be gratefull. I guess that it has to do with the special
  327.          nature of the .bss section. Or maybe this is because the
  328.          bss symbols are declared in the common section and can
  329.          be resized later. Can it break code some where ? */
  330.       ri_table[i].r_symndx = (S_GET_SEGMENT (symbolP) == SEG_TEXT
  331.                   ? dot_text_symbol->sy_number
  332.                   : (S_GET_SEGMENT (symbolP) == SEG_DATA
  333.                      ? dot_data_symbol->sy_number
  334.                      : ((SF_GET_LOCAL (symbolP)
  335.                      ? dot_bss_symbol->sy_number
  336.                      : symbolP->sy_number))));    /* bss or undefined */
  337.  
  338.       /* md_ri_to_chars((char *) &ri, ri); *//* Last step : write md f */
  339.  
  340.       i++;
  341.     }            /* if there's a symbol */
  342.     }                /* for each fixP */
  343.  
  344.   /* AIX ld prefer to have the reloc table with r_vaddr sorted.
  345.      But sorting it should not hurt any other ld.  */
  346.   qsort (ri_table, count, sizeof (*ri_table), reloc_compare);
  347.  
  348.   for (i = 0; i < count; i++)
  349.     {
  350. #ifdef BFD_HEADERS
  351.       *where += bfd_coff_swap_reloc_out (stdoutput, &ri_table[i], *where);
  352. # ifdef TC_A29K
  353.       /* The 29k has a special kludge for the high 16 bit reloc.
  354.      Two relocations are emmited, R_IHIHALF, and R_IHCONST.
  355.      The second one doesn't contain a symbol, but uses the
  356.      value for offset */
  357.       if (ri_table[i].r_type == R_IHIHALF)
  358.     {
  359.       /* now emit the second bit */
  360.       ri_table[i].r_type = R_IHCONST;
  361.       ri_table[i].r_symndx = fixP->fx_addnumber;
  362.       *where += bfd_coff_swap_reloc_out (stdoutput, &ri_table[i],
  363.                          *where);
  364.     }
  365. # endif                /* TC_A29K */
  366.  
  367. #else /* not BFD_HEADERS */
  368.       append (where, (char *) &ri_table[i], RELSZ);
  369. #endif /* not BFD_HEADERS */
  370.  
  371. #ifdef TC_I960
  372.       if (callj_table[i])
  373.     {
  374.       ri_table[i].r_type = R_OPTCALL;
  375. # ifdef BFD_HEADERS
  376.       *where += bfd_coff_swap_reloc_out (stdoutput, &ri_table[i],
  377.                          *where);
  378. # else
  379.       append (where, (char *) &ri_table[i], (unsigned long) RELSZ);
  380. # endif                /* BFD_HEADERS */
  381.     }            /* if it's a callj, do it again for the opcode */
  382. #endif /* TC_I960 */
  383.     }
  384.  
  385.   free (ri_table);
  386. #ifdef TC_I960
  387.   free (callj_table);
  388. #endif
  389.  
  390.   return;
  391. }                /* obj_emit_relocations() */
  392.  
  393. /* Coff file generation & utilities */
  394.  
  395. #ifdef BFD_HEADERS
  396. void
  397. obj_header_append (where, headers)
  398.      char **where;
  399.      object_headers *headers;
  400. {
  401.   tc_headers_hook (headers);
  402.   *where += bfd_coff_swap_filehdr_out (stdoutput, &(headers->filehdr), *where);
  403. #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
  404.   *where += bfd_coff_swap_aouthdr_out (stdoutput, &(headers->aouthdr), *where);
  405. #endif
  406.   obj_coff_section_header_append (where, &text_section_header);
  407.   obj_coff_section_header_append (where, &data_section_header);
  408.   obj_coff_section_header_append (where, &bss_section_header);
  409. }
  410.  
  411. #else /* ! BFD_HEADERS */
  412.  
  413. void
  414. obj_header_append (where, headers)
  415.      char **where;
  416.      object_headers *headers;
  417. {
  418.   tc_headers_hook (headers);
  419.  
  420. #ifdef CROSS_COMPILE
  421.   /* Eventually swap bytes for cross compilation for file header */
  422.   md_number_to_chars (*where, headers->filehdr.f_magic, sizeof (headers->filehdr.f_magic));
  423.   *where += sizeof (headers->filehdr.f_magic);
  424.   md_number_to_chars (*where, headers->filehdr.f_nscns, sizeof (headers->filehdr.f_nscns));
  425.   *where += sizeof (headers->filehdr.f_nscns);
  426.   md_number_to_chars (*where, headers->filehdr.f_timdat, sizeof (headers->filehdr.f_timdat));
  427.   *where += sizeof (headers->filehdr.f_timdat);
  428.   md_number_to_chars (*where, headers->filehdr.f_symptr, sizeof (headers->filehdr.f_symptr));
  429.   *where += sizeof (headers->filehdr.f_symptr);
  430.   md_number_to_chars (*where, headers->filehdr.f_nsyms, sizeof (headers->filehdr.f_nsyms));
  431.   *where += sizeof (headers->filehdr.f_nsyms);
  432.   md_number_to_chars (*where, headers->filehdr.f_opthdr, sizeof (headers->filehdr.f_opthdr));
  433.   *where += sizeof (headers->filehdr.f_opthdr);
  434.   md_number_to_chars (*where, headers->filehdr.f_flags, sizeof (headers->filehdr.f_flags));
  435.   *where += sizeof (headers->filehdr.f_flags);
  436.  
  437. #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
  438.   /* Eventually swap bytes for cross compilation for a.out header */
  439.   md_number_to_chars (*where, headers->aouthdr.magic, sizeof (headers->aouthdr.magic));
  440.   *where += sizeof (headers->aouthdr.magic);
  441.   md_number_to_chars (*where, headers->aouthdr.vstamp, sizeof (headers->aouthdr.vstamp));
  442.   *where += sizeof (headers->aouthdr.vstamp);
  443.   md_number_to_chars (*where, headers->aouthdr.tsize, sizeof (headers->aouthdr.tsize));
  444.   *where += sizeof (headers->aouthdr.tsize);
  445.   md_number_to_chars (*where, headers->aouthdr.dsize, sizeof (headers->aouthdr.dsize));
  446.   *where += sizeof (headers->aouthdr.dsize);
  447.   md_number_to_chars (*where, headers->aouthdr.bsize, sizeof (headers->aouthdr.bsize));
  448.   *where += sizeof (headers->aouthdr.bsize);
  449.   md_number_to_chars (*where, headers->aouthdr.entry, sizeof (headers->aouthdr.entry));
  450.   *where += sizeof (headers->aouthdr.entry);
  451.   md_number_to_chars (*where, headers->aouthdr.text_start, sizeof (headers->aouthdr.text_start));
  452.   *where += sizeof (headers->aouthdr.text_start);
  453.   md_number_to_chars (*where, headers->aouthdr.data_start, sizeof (headers->aouthdr.data_start));
  454.   *where += sizeof (headers->aouthdr.data_start);
  455.   md_number_to_chars (*where, headers->aouthdr.tagentries, sizeof (headers->aouthdr.tagentries));
  456.   *where += sizeof (headers->aouthdr.tagentries);
  457. #endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
  458.  
  459. #else /* CROSS_COMPILE */
  460.  
  461.   append (where, (char *) &headers->filehdr, sizeof (headers->filehdr));
  462. #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
  463.   append (where, (char *) &headers->aouthdr, sizeof (headers->aouthdr));
  464. #endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
  465.  
  466. #endif /* CROSS_COMPILE */
  467.  
  468.   /* Output the section headers */
  469.   obj_coff_section_header_append (where, &text_section_header);
  470.   obj_coff_section_header_append (where, &data_section_header);
  471.   obj_coff_section_header_append (where, &bss_section_header);
  472.  
  473.   return;
  474. }                /* obj_header_append() */
  475.  
  476. #endif /* ! BFD_HEADERS */
  477.  
  478. void
  479. obj_symbol_to_chars (where, symbolP)
  480.      char **where;
  481.      symbolS *symbolP;
  482. {
  483. #ifdef BFD_HEADERS
  484.   unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;
  485.   unsigned int i;
  486.  
  487.   if (S_GET_SEGMENT (symbolP) == SEG_REGISTER)
  488.     {
  489.       S_SET_SEGMENT (symbolP, SEG_ABSOLUTE);
  490.     }
  491.   *where += bfd_coff_swap_sym_out (stdoutput, &symbolP->sy_symbol.ost_entry,
  492.                    *where);
  493.  
  494.   for (i = 0; i < numaux; i++)
  495.     {
  496.       *where += bfd_coff_swap_aux_out (stdoutput,
  497.                        &symbolP->sy_symbol.ost_auxent[i],
  498.                        S_GET_DATA_TYPE (symbolP),
  499.                        S_GET_STORAGE_CLASS (symbolP),
  500.                        *where);
  501.     }
  502.  
  503. #else /* BFD_HEADERS */
  504.   SYMENT *syment = &symbolP->sy_symbol.ost_entry;
  505.   int i;
  506.   char numaux = syment->n_numaux;
  507.   unsigned short type = S_GET_DATA_TYPE (symbolP);
  508.  
  509. #ifdef CROSS_COMPILE
  510.   md_number_to_chars (*where, syment->n_value, sizeof (syment->n_value));
  511.   *where += sizeof (syment->n_value);
  512.   md_number_to_chars (*where, syment->n_scnum, sizeof (syment->n_scnum));
  513.   *where += sizeof (syment->n_scnum);
  514.   md_number_to_chars (*where, 0, sizeof (short));    /* pad n_flags */
  515.   *where += sizeof (short);
  516.   md_number_to_chars (*where, syment->n_type, sizeof (syment->n_type));
  517.   *where += sizeof (syment->n_type);
  518.   md_number_to_chars (*where, syment->n_sclass, sizeof (syment->n_sclass));
  519.   *where += sizeof (syment->n_sclass);
  520.   md_number_to_chars (*where, syment->n_numaux, sizeof (syment->n_numaux));
  521.   *where += sizeof (syment->n_numaux);
  522. #else /* CROSS_COMPILE */
  523.   append (where, (char *) syment, sizeof (*syment));
  524. #endif /* CROSS_COMPILE */
  525.  
  526.   /* Should do the following:
  527.      if (.file entry) MD(..)... else if (static entry) MD(..) */
  528.   if (numaux > OBJ_COFF_MAX_AUXENTRIES)
  529.     {
  530.       as_bad ("Internal error? too many auxents for symbol");
  531.     }                /* too many auxents */
  532.  
  533.   for (i = 0; i < numaux; ++i)
  534.     {
  535. #ifdef CROSS_COMPILE
  536. #if 0                /* This code has never been tested */
  537.       /* The most common case, x_sym entry. */
  538.       if ((SF_GET (symbolP) & (SF_FILE | SF_STATICS)) == 0)
  539.     {
  540.       md_number_to_chars (*where, auxP->x_sym.x_tagndx, sizeof (auxP->x_sym.x_tagndx));
  541.       *where += sizeof (auxP->x_sym.x_tagndx);
  542.       if (ISFCN (type))
  543.         {
  544.           md_number_to_chars (*where, auxP->x_sym.x_misc.x_fsize, sizeof (auxP->x_sym.x_misc.x_fsize));
  545.           *where += sizeof (auxP->x_sym.x_misc.x_fsize);
  546.         }
  547.       else
  548.         {
  549.           md_number_to_chars (*where, auxP->x_sym.x_misc.x_lnno, sizeof (auxP->x_sym.x_misc.x_lnno));
  550.           *where += sizeof (auxP->x_sym.x_misc.x_lnno);
  551.           md_number_to_chars (*where, auxP->x_sym.x_misc.x_size, sizeof (auxP->x_sym.x_misc.x_size));
  552.           *where += sizeof (auxP->x_sym.x_misc.x_size);
  553.         }
  554.       if (ISARY (type))
  555.         {
  556.           register int index;
  557.           for (index = 0; index < DIMNUM; index++)
  558.         md_number_to_chars (*where, auxP->x_sym.x_fcnary.x_ary.x_dimen[index], sizeof (auxP->x_sym.x_fcnary.x_ary.x_dimen[index]));
  559.           *where += sizeof (auxP->x_sym.x_fcnary.x_ary.x_dimen[index]);
  560.         }
  561.       else
  562.         {
  563.           md_number_to_chars (*where, auxP->x_sym.x_fcnary.x_fcn.x_lnnoptr, sizeof (auxP->x_sym.x_fcnary.x_fcn.x_lnnoptr));
  564.           *where += sizeof (auxP->x_sym.x_fcnary.x_fcn.x_lnnoptr);
  565.           md_number_to_chars (*where, auxP->x_sym.x_fcnary.x_fcn.x_endndx, sizeof (auxP->x_sym.x_fcnary.x_fcn.x_endndx));
  566.           *where += sizeof (auxP->x_sym.x_fcnary.x_fcn.x_endndx);
  567.         }
  568.       md_number_to_chars (*where, auxP->x_sym.x_tvndx, sizeof (auxP->x_sym.x_tvndx));
  569.       *where += sizeof (auxP->x_sym.x_tvndx);
  570.     }
  571.       else if (SF_GET_FILE (symbolP))
  572.     {            /* .file */
  573.       ;
  574.     }
  575.       else if (SF_GET_STATICS (symbolP))
  576.     {            /* .text, .data, .bss symbols */
  577.       md_number_to_chars (*where, auxP->x_scn.x_scnlen, sizeof (auxP->x_scn.x_scnlen));
  578.       *where += sizeof (auxP->x_scn.x_scnlen);
  579.       md_number_to_chars (*where, auxP->x_scn.x_nreloc, sizeof (auxP->x_scn.x_nreloc));
  580.       *where += sizeof (auxP->x_scn.x_nreloc);
  581.       md_number_to_chars (*where, auxP->x_scn.x_nlinno, sizeof (auxP->x_scn.x_nlinno));
  582.       *where += sizeof (auxP->x_scn.x_nlinno);
  583.     }
  584. #endif /* 0 */
  585. #else /* CROSS_COMPILE */
  586.       append (where, (char *) &symbolP->sy_symbol.ost_auxent[i], sizeof (symbolP->sy_symbol.ost_auxent[i]));
  587. #endif /* CROSS_COMPILE */
  588.  
  589.     };                /* for each aux in use */
  590. #endif /* BFD_HEADERS */
  591.   return;
  592. }                /* obj_symbol_to_chars() */
  593.  
  594. #ifdef BFD_HEADERS
  595. static void
  596. obj_coff_section_header_append (where, header)
  597.      char **where;
  598.      struct internal_scnhdr *header;
  599. {
  600.   *where += bfd_coff_swap_scnhdr_out (stdoutput, header, *where);
  601. }
  602.  
  603. #else
  604. static void
  605. obj_coff_section_header_append (where, header)
  606.      char **where;
  607.      SCNHDR *header;
  608. {
  609. #ifdef CROSS_COMPILE
  610.   memcpy (*where, header->s_name, sizeof (header->s_name));
  611.   *where += sizeof (header->s_name);
  612.  
  613.   md_number_to_chars (*where, header->s_paddr, sizeof (header->s_paddr));
  614.   *where += sizeof (header->s_paddr);
  615.  
  616.   md_number_to_chars (*where, header->s_vaddr, sizeof (header->s_vaddr));
  617.   *where += sizeof (header->s_vaddr);
  618.  
  619.   md_number_to_chars (*where, header->s_size, sizeof (header->s_size));
  620.   *where += sizeof (header->s_size);
  621.  
  622.   md_number_to_chars (*where, header->s_scnptr, sizeof (header->s_scnptr));
  623.   *where += sizeof (header->s_scnptr);
  624.  
  625.   md_number_to_chars (*where, header->s_relptr, sizeof (header->s_relptr));
  626.   *where += sizeof (header->s_relptr);
  627.  
  628.   md_number_to_chars (*where, header->s_lnnoptr, sizeof (header->s_lnnoptr));
  629.   *where += sizeof (header->s_lnnoptr);
  630.  
  631.   md_number_to_chars (*where, header->s_nreloc, sizeof (header->s_nreloc));
  632.   *where += sizeof (header->s_nreloc);
  633.  
  634.   md_number_to_chars (*where, header->s_nlnno, sizeof (header->s_nlnno));
  635.   *where += sizeof (header->s_nlnno);
  636.  
  637.   md_number_to_chars (*where, header->s_flags, sizeof (header->s_flags));
  638.   *where += sizeof (header->s_flags);
  639.  
  640. #ifdef TC_I960
  641.   md_number_to_chars (*where, header->s_align, sizeof (header->s_align));
  642.   *where += sizeof (header->s_align);
  643. #endif /* TC_I960 */
  644.  
  645. #else /* CROSS_COMPILE */
  646.  
  647.   append (where, (char *) header, sizeof (*header));
  648.  
  649. #endif /* CROSS_COMPILE */
  650.  
  651.   return;
  652. }                /* obj_coff_section_header_append() */
  653.  
  654. #endif
  655. void
  656. obj_emit_symbols (where, symbol_rootP)
  657.      char **where;
  658.      symbolS *symbol_rootP;
  659. {
  660.   symbolS *symbolP;
  661.   /*
  662.      * Emit all symbols left in the symbol chain.
  663.      */
  664.   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
  665.     {
  666.       /* Used to save the offset of the name. It is used to point
  667.            to the string in memory but must be a file offset. */
  668.       register char *temp;
  669.  
  670.       tc_coff_symbol_emit_hook (symbolP);
  671.  
  672.       temp = S_GET_NAME (symbolP);
  673.       if (SF_GET_STRING (symbolP))
  674.     {
  675.       S_SET_OFFSET (symbolP, symbolP->sy_name_offset);
  676.       S_SET_ZEROES (symbolP, 0);
  677.     }
  678.       else
  679.     {
  680.       memset (symbolP->sy_symbol.ost_entry.n_name, '\0', SYMNMLEN);
  681.       strncpy (symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN);
  682.     }
  683.       obj_symbol_to_chars (where, symbolP);
  684.       S_SET_NAME (symbolP, temp);
  685.     }
  686. }                /* obj_emit_symbols() */
  687.  
  688. #endif /* ! BFD_ASSEMBLER */
  689.  
  690. /* Merge a debug symbol containing debug information into a normal symbol. */
  691.  
  692. void
  693. c_symbol_merge (debug, normal)
  694.      symbolS *debug;
  695.      symbolS *normal;
  696. {
  697.   S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
  698.   S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
  699.  
  700.   if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
  701.     /* take the most we have */
  702.     S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
  703.  
  704.   if (S_GET_NUMBER_AUXILIARY (debug) > 0)
  705.     {
  706.       /* Move all the auxiliary information.  */
  707. #ifdef BFD_ASSEMBLER
  708.       /* @@ How many fields do we want to preserve?  Would it make more
  709.      sense to pick and choose those we want to copy?  Should look
  710.      into this further....  [raeburn:19920512.2209EST]  */
  711.       alent *linenos;
  712.       linenos = coffsymbol (normal->bsym)->lineno;
  713.       memcpy ((char *) &coffsymbol (normal->bsym)->native,
  714.           (char *) &coffsymbol (debug->bsym)->native,
  715.           S_GET_NUMBER_AUXILIARY(debug) * AUXESZ);
  716.       coffsymbol (normal->bsym)->lineno = linenos;
  717. #else
  718.       memcpy ((char *) &normal->sy_symbol.ost_auxent[0],
  719.           (char *) &debug->sy_symbol.ost_auxent[0],
  720.           S_GET_NUMBER_AUXILIARY (debug) * AUXESZ);
  721. #endif
  722.     }
  723.  
  724.   /* Move the debug flags. */
  725.   SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
  726. }                /* c_symbol_merge() */
  727.  
  728. static symbolS *previous_file_symbol;
  729. void
  730. c_dot_file_symbol (filename)
  731.      char *filename;
  732. {
  733.   symbolS *symbolP;
  734.  
  735. #ifdef BFD_ASSEMBLER
  736.   symbolP = symbol_new (filename, &bfd_abs_section, 0,
  737.             &zero_address_frag);
  738. #else
  739.   symbolP = symbol_new (".file",
  740.             SEG_DEBUG,
  741.             0,
  742.             &zero_address_frag);
  743. #endif
  744.  
  745.   S_SET_STORAGE_CLASS (symbolP, C_FILE);
  746.   S_SET_NUMBER_AUXILIARY (symbolP, 1);
  747.  
  748. #ifdef BFD_ASSEMBLER
  749.   symbolP->bsym->flags = BSF_DEBUGGING;
  750. #else
  751.   if (strlen(filename) > 14) 
  752.     {
  753.       /* This won't fit into a 14 char space, it will go into the string
  754.      table.  */
  755.       symbolP->sy_symbol.ost_auxent->x_file.x_n.x_zeroes = 0;
  756.       (&(symbolP->sy_symbol.ost_auxent->x_file.x_n.x_offset))[0] = string_byte_count;
  757.       (&(symbolP->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1] = (int)filename;
  758.     }
  759.   else 
  760.     {
  761.       SA_SET_FILE_FNAME (symbolP, filename);
  762.     }
  763.   SF_SET_DEBUG (symbolP);
  764. #endif
  765.  
  766. #ifndef NO_LISTING
  767.   {
  768.     extern int listing;
  769.     if (listing)
  770.       {
  771.     listing_source_file (filename);
  772.       }
  773.   }
  774. #endif
  775.  
  776.   S_SET_VALUE (symbolP, (long) previous_file_symbol);
  777.  
  778.   previous_file_symbol = symbolP;
  779.  
  780.   /* Make sure that the symbol is first on the symbol chain */
  781.   if (symbol_rootP != symbolP)
  782.     {
  783.       if (symbolP == symbol_lastP)
  784.     {
  785.       symbol_lastP = symbol_lastP->sy_previous;
  786.     }            /* if it was the last thing on the list */
  787.  
  788.       symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
  789.       symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
  790.       symbol_rootP = symbolP;
  791.     }                /* if not first on the list */
  792. }
  793.  
  794. /*
  795.  * Build a 'section static' symbol.
  796.  */
  797.  
  798. char *
  799. c_section_symbol (name, value, length, nreloc, nlnno)
  800.      char *name;
  801.      long value;
  802.      long length;
  803.      unsigned short nreloc;
  804.      unsigned short nlnno;
  805. {
  806.   symbolS *symbolP;
  807.  
  808.   symbolP = symbol_new (name,
  809.             (name[1] == 't'
  810.              ? text_section
  811.              : name[1] == 'd'
  812.              ? data_section
  813.              : bss_section),
  814.             value,
  815.             &zero_address_frag);
  816.  
  817.   S_SET_STORAGE_CLASS (symbolP, C_STAT);
  818.   S_SET_NUMBER_AUXILIARY (symbolP, 1);
  819.  
  820.   SA_SET_SCN_SCNLEN (symbolP, length);
  821.   SA_SET_SCN_NRELOC (symbolP, nreloc);
  822.   SA_SET_SCN_NLINNO (symbolP, nlnno);
  823.  
  824.   SF_SET_STATICS (symbolP);
  825.  
  826.   return (char *) symbolP;
  827. }                /* c_section_symbol() */
  828.  
  829. void
  830. c_section_header (header,
  831.           name,
  832.           core_address,
  833.           size,
  834.           data_ptr,
  835.           reloc_ptr,
  836.           lineno_ptr,
  837.           reloc_number,
  838.           lineno_number,
  839.           alignment)
  840. #ifdef BFD_HEADERS
  841.      struct internal_scnhdr *header;
  842. #else
  843.      SCNHDR *header;
  844. #endif
  845.      char *name;
  846.      long core_address;
  847.      long size;
  848.      long data_ptr;
  849.      long reloc_ptr;
  850.      long lineno_ptr;
  851.      long reloc_number;
  852.      long lineno_number;
  853.      long alignment;
  854. {
  855.   strncpy (header->s_name, name, 8);
  856.   header->s_paddr = header->s_vaddr = core_address;
  857.   header->s_scnptr = ((header->s_size = size) != 0) ? data_ptr : 0;
  858.   header->s_relptr = reloc_ptr;
  859.   header->s_lnnoptr = lineno_ptr;
  860.   header->s_nreloc = reloc_number;
  861.   header->s_nlnno = lineno_number;
  862.  
  863. #ifdef OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT
  864. #ifdef OBJ_COFF_BROKEN_ALIGNMENT
  865.   header->s_align = ((name[1] == 'b' || (size > 0)) ? 16 : 0);
  866. #else
  867.   header->s_align = ((alignment == 0)
  868.              ? 0
  869.              : (1 << alignment));
  870. #endif /* OBJ_COFF_BROKEN_ALIGNMENT */
  871. #endif /* OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT */
  872.  
  873.   header->s_flags = STYP_REG | (name[1] == 't'
  874.                 ? STYP_TEXT
  875.                 : name[1] == 'd'
  876.                 ? STYP_DATA
  877.                 : name[1] == 'b'
  878.                 ? STYP_BSS
  879.                 : STYP_INFO);
  880. }
  881.  
  882. /* Line number handling */
  883.  
  884. #ifdef BFD_ASSEMBLER
  885.  
  886. /* Symbol of last function, which we should hang line#s off of.  */
  887. symbolS *function_lineoff;
  888.  
  889. #else
  890.  
  891. /* Offset in line#s where the last function started (the odd entry for
  892.    line #0). */
  893. int function_lineoff = -1;
  894.  
  895. int text_lineno_number;
  896.  
  897. /* We use this to build pointers from .bf's into the linetable.  It
  898.    should match exactly the values that are later assigned in
  899.    text_lineno_number by write.c. */
  900. int our_lineno_number;
  901.  
  902. lineno *lineno_lastP;
  903. #endif
  904.  
  905. #ifndef BFD_ASSEMBLER
  906. int
  907. c_line_new (paddr, line_number, frag)
  908.      long paddr;
  909.      unsigned short line_number;
  910.      fragS *frag;
  911. {
  912.   lineno *new_line = (lineno *) xmalloc (sizeof (lineno));
  913.  
  914.   new_line->line.l_addr.l_paddr = paddr;
  915.   new_line->line.l_lnno = line_number;
  916.   new_line->frag = (char *) frag;
  917.   new_line->next = (lineno *) 0;
  918.  
  919.   if (lineno_rootP == (lineno *) 0)
  920.     lineno_rootP = new_line;
  921.   else
  922.     lineno_lastP->next = new_line;
  923.   lineno_lastP = new_line;
  924.   return LINESZ * our_lineno_number++;
  925. }
  926. #endif
  927.  
  928. void
  929. obj_emit_lineno (where, line, file_start)
  930.      char **where;
  931. #ifndef BFD_ASSEMBLER /* sigh */
  932.      lineno *line;
  933. #endif
  934.      char *file_start;
  935. {
  936. #ifndef BFD_ASSEMBLER
  937. #ifdef BFD_HEADERS
  938.   struct bfd_internal_lineno *line_entry;
  939. #else
  940.   LINENO *line_entry;
  941. #endif
  942.   for (; line; line = line->next)
  943.     {
  944.       line_entry = &line->line;
  945.  
  946.       /* FIXME-SOMEDAY Resolving the sy_number of function linno's used to be
  947.      done in write_object_file() but their symbols need a fileptr to the
  948.      lnno, so I moved this resolution check here.  xoxorich. */
  949.  
  950.       if (line_entry->l_lnno == 0)
  951.     {
  952.       /* There is a good chance that the symbol pointed to
  953.          is not the one that will be emitted and that the
  954.          sy_number is not accurate. */
  955.       symbolS *symbolP;
  956.  
  957.       symbolP = (symbolS *) line_entry->l_addr.l_symndx;
  958.  
  959.       line_entry->l_addr.l_symndx = symbolP->sy_number;
  960.       symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_lnnoptr = *where - file_start;
  961.  
  962.     }            /* if this is a function linno */
  963. #ifdef BFD_HEADERS
  964.       *where += bfd_coff_swap_lineno_out (stdoutput, line_entry, *where);
  965. #else
  966.       /* No matter which member of the union we process, they are
  967.      both long. */
  968. #ifdef CROSS_COMPILE
  969.       md_number_to_chars (*where, line_entry->l_addr.l_paddr, sizeof (line_entry->l_addr.l_paddr));
  970.       *where += sizeof (line_entry->l_addr.l_paddr);
  971.  
  972.       md_number_to_chars (*where, line_entry->l_lnno, sizeof (line_entry->l_lnno));
  973.       *where += sizeof (line_entry->l_lnno);
  974.  
  975. #ifdef TC_I960
  976.       **where = '0';
  977.       ++*where;
  978.       **where = '0';
  979.       ++*where;
  980. #endif /* TC_I960 */
  981.  
  982. #else /* CROSS_COMPILE */
  983.       append (where, (char *) line_entry, LINESZ);
  984. #endif /* CROSS_COMPILE */
  985. #endif /* BFD_HEADERS */
  986.     }                /* for each line number */
  987. #else /* BFD_ASSEMBLER */
  988.   abort ();
  989. #endif /* BFD_ASSEMBLER */
  990. }
  991.  
  992. void
  993. obj_symbol_new_hook (symbolP)
  994.      symbolS *symbolP;
  995. {
  996.   char underscore = 0;        /* Symbol has leading _ */
  997.  
  998. #ifdef BFD_ASSEMBLER
  999.   {
  1000.     long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
  1001.     char *s = (char *) bfd_alloc_by_size_t (stdoutput, sz);
  1002.     memset (s, 0, sz);
  1003.     coffsymbol (symbolP->bsym)->native = (combined_entry_type *) s;
  1004.   }
  1005. #else
  1006.   /* Effective symbol */
  1007.   /* Store the pointer in the offset. */
  1008.   S_SET_ZEROES (symbolP, 0L);
  1009.   /* Additional information */
  1010.   symbolP->sy_symbol.ost_flags = 0;
  1011.   /* Auxiliary entries */
  1012.   memset ((char *) &symbolP->sy_symbol.ost_auxent[0], '\0', AUXESZ);
  1013. #endif
  1014.   S_SET_DATA_TYPE (symbolP, T_NULL);
  1015.   S_SET_STORAGE_CLASS (symbolP, 0);
  1016.   S_SET_NUMBER_AUXILIARY (symbolP, 0);
  1017.  
  1018. #ifdef STRIP_UNDERSCORE
  1019.   /* Remove leading underscore at the beginning of the symbol.
  1020.      This is to be compatible with the standard librairies.  */
  1021.   if (*S_GET_NAME (symbolP) == '_')
  1022.     {
  1023.       underscore = 1;
  1024.       S_SET_NAME (symbolP, S_GET_NAME (symbolP) + 1);
  1025.     }
  1026. #endif /* STRIP_UNDERSCORE */
  1027.  
  1028.   if (S_IS_STRING (symbolP))
  1029.     SF_SET_STRING (symbolP);
  1030.   if (!underscore && S_IS_LOCAL (symbolP))
  1031.     SF_SET_LOCAL (symbolP);
  1032. }
  1033.  
  1034. /* stack stuff */
  1035. stack *
  1036. stack_init (chunk_size, element_size)
  1037.      unsigned long chunk_size;
  1038.      unsigned long element_size;
  1039. {
  1040.   stack *st;
  1041.  
  1042.   st = (stack *) malloc (sizeof (stack));
  1043.   if (!st)
  1044.     return 0;
  1045.   st->data = malloc (chunk_size);
  1046.   if (!st->data)
  1047.     {
  1048.       free (st);
  1049.       return 0;
  1050.     }
  1051.   st->pointer = 0;
  1052.   st->size = chunk_size;
  1053.   st->chunk_size = chunk_size;
  1054.   st->element_size = element_size;
  1055.   return st;
  1056. }
  1057.  
  1058. void
  1059. stack_delete (st)
  1060.      stack *st;
  1061. {
  1062.   free (st->data);
  1063.   free (st);
  1064. }
  1065.  
  1066. char *
  1067. stack_push (st, element)
  1068.      stack *st;
  1069.      char *element;
  1070. {
  1071.   if (st->pointer + st->element_size >= st->size)
  1072.     {
  1073.       st->size += st->chunk_size;
  1074.       if ((st->data = xrealloc (st->data, st->size)) == (char *) 0)
  1075.     return (char *) 0;
  1076.     }
  1077.   memcpy (st->data + st->pointer, element, st->element_size);
  1078.   st->pointer += st->element_size;
  1079.   return st->data + st->pointer;
  1080. }                /* stack_push() */
  1081.  
  1082. char *
  1083. stack_pop (st)
  1084.      stack *st;
  1085. {
  1086.   if ((st->pointer -= st->element_size) < 0)
  1087.     {
  1088.       st->pointer = 0;
  1089.       return (char *) 0;
  1090.     }
  1091.   return st->data + st->pointer;
  1092. }
  1093.  
  1094. char *
  1095. stack_top (st)
  1096.      stack *st;
  1097. {
  1098.   return st->data + st->pointer - st->element_size;
  1099. }
  1100.  
  1101.  
  1102. /*
  1103.  * Handle .ln directives.
  1104.  */
  1105.  
  1106. #ifdef BFD_ASSEMBLER
  1107. static symbolS *current_lineno_sym;
  1108. static struct line_no *line_nos;
  1109.  
  1110. static void
  1111. add_lineno (frag, offset, num)
  1112.      fragS *frag;
  1113.      int offset;
  1114.      int num;
  1115. {
  1116.   struct line_no *new_line = (struct line_no *) bfd_alloc_by_size_t (stdoutput,
  1117.                                      sizeof (struct line_no));
  1118.   if (!current_lineno_sym)
  1119.     {
  1120.       abort ();
  1121.     }
  1122.   new_line->next = line_nos;
  1123.   new_line->frag = frag;
  1124.   new_line->l.line_number = num;
  1125.   new_line->l.u.offset = offset;
  1126.   line_nos = new_line;
  1127. }
  1128.  
  1129. static void
  1130. add_linesym (sym)
  1131.      symbolS *sym;
  1132. {
  1133.   if (line_nos)
  1134.     {
  1135.       add_lineno (0, 0, 0);
  1136.       coffsymbol (current_lineno_sym->bsym)->lineno = (alent *) line_nos;
  1137.       line_nos = 0;
  1138.     }
  1139.   current_lineno_sym = sym;
  1140. }
  1141. #endif
  1142.  
  1143. static void
  1144. obj_coff_ln ()
  1145. {
  1146.   int l;
  1147.   if (def_symbol_in_progress != NULL)
  1148.     {
  1149.       as_warn (".ln pseudo-op inside .def/.endef: ignored.");
  1150.       demand_empty_rest_of_line ();
  1151.       return;
  1152.     }
  1153.  
  1154.   l = get_absolute_expression ();
  1155. #ifdef BFD_ASSEMBLER
  1156.   add_lineno (frag_now, frag_now_fix (), l);
  1157. #else
  1158.   c_line_new (frag_now_fix (), l, frag_now);
  1159. #endif
  1160.  
  1161. #ifndef NO_LISTING
  1162.   {
  1163.     extern int listing;
  1164.  
  1165.     if (listing)
  1166.       {
  1167.     listing_source_line (l + line_base - 1);
  1168.       }
  1169.   }
  1170. #endif
  1171.  
  1172.   demand_empty_rest_of_line ();
  1173. }                /* obj_coff_ln() */
  1174.  
  1175. /*
  1176.  *            def()
  1177.  *
  1178.  * Handle .def directives.
  1179.  *
  1180.  * One might ask : why can't we symbol_new if the symbol does not
  1181.  * already exist and fill it with debug information.  Because of
  1182.  * the C_EFCN special symbol. It would clobber the value of the
  1183.  * function symbol before we have a chance to notice that it is
  1184.  * a C_EFCN. And a second reason is that the code is more clear this
  1185.  * way. (at least I think it is :-).
  1186.  *
  1187.  */
  1188.  
  1189. #define SKIP_SEMI_COLON()    while (*input_line_pointer++ != ';')
  1190. #define SKIP_WHITESPACES()    while (*input_line_pointer == ' ' || \
  1191.                        *input_line_pointer == '\t') \
  1192.     input_line_pointer++;
  1193.  
  1194. static void
  1195. obj_coff_def (what)
  1196.      int what;
  1197. {
  1198.   char name_end;        /* Char after the end of name */
  1199.   char *symbol_name;        /* Name of the debug symbol */
  1200.   char *symbol_name_copy;    /* Temporary copy of the name */
  1201.   unsigned int symbol_name_length;
  1202.  
  1203.   if (def_symbol_in_progress != NULL)
  1204.     {
  1205.       as_warn (".def pseudo-op used inside of .def/.endef: ignored.");
  1206.       demand_empty_rest_of_line ();
  1207.       return;
  1208.     }                /* if not inside .def/.endef */
  1209.  
  1210.   SKIP_WHITESPACES ();
  1211.  
  1212.   symbol_name = input_line_pointer;
  1213. #ifdef STRIP_UNDERSCORE
  1214.   if (symbol_name[0] == '_' && symbol_name[1] != 0)
  1215.     symbol_name++;
  1216. #endif /* STRIP_UNDERSCORE */
  1217.  
  1218.   name_end = get_symbol_end ();
  1219.   symbol_name_length = strlen (symbol_name);
  1220.   symbol_name_copy = xmalloc (symbol_name_length + 1);
  1221.   strcpy (symbol_name_copy, symbol_name);
  1222.  
  1223.   /* Initialize the new symbol */
  1224. #ifdef BFD_ASSEMBLER
  1225.   def_symbol_in_progress = symbol_make (symbol_name_copy);
  1226. #else
  1227.   def_symbol_in_progress = (symbolS *) obstack_alloc (¬es, sizeof (*def_symbol_in_progress));
  1228.   memset (def_symbol_in_progress, '\0', sizeof (*def_symbol_in_progress));
  1229.  
  1230.   S_SET_NAME (def_symbol_in_progress, symbol_name_copy);
  1231.   def_symbol_in_progress->sy_name_offset = ~0;
  1232.   def_symbol_in_progress->sy_number = ~0;
  1233. #endif
  1234.  
  1235.   def_symbol_in_progress->sy_frag = &zero_address_frag;
  1236.  
  1237.   if (S_IS_STRING (def_symbol_in_progress))
  1238.     SF_SET_STRING (def_symbol_in_progress);
  1239.  
  1240.   *input_line_pointer = name_end;
  1241.  
  1242.   demand_empty_rest_of_line ();
  1243. }
  1244.  
  1245. unsigned int dim_index;
  1246. static void
  1247. obj_coff_endef ()
  1248. {
  1249.   symbolS *symbolP;
  1250.   /* DIM BUG FIX sac@cygnus.com */
  1251.   dim_index = 0;
  1252.   if (def_symbol_in_progress == NULL)
  1253.     {
  1254.       as_warn (".endef pseudo-op used outside of .def/.endef: ignored.");
  1255.       demand_empty_rest_of_line ();
  1256.       return;
  1257.     }                /* if not inside .def/.endef */
  1258.  
  1259.   /* Set the section number according to storage class. */
  1260.   switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
  1261.     {
  1262.     case C_STRTAG:
  1263.     case C_ENTAG:
  1264.     case C_UNTAG:
  1265.       SF_SET_TAG (def_symbol_in_progress);
  1266.       /* intentional fallthrough */
  1267.     case C_FILE:
  1268.     case C_TPDEF:
  1269.       SF_SET_DEBUG (def_symbol_in_progress);
  1270. #ifdef BFD_ASSEMBLER
  1271.       S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ());
  1272. #else
  1273.       S_SET_SEGMENT (def_symbol_in_progress, SEG_DEBUG);
  1274. #endif
  1275.       break;
  1276.  
  1277.     case C_EFCN:
  1278.       SF_SET_LOCAL (def_symbol_in_progress);    /* Do not emit this symbol. */
  1279.       /* intentional fallthrough */
  1280.     case C_BLOCK:
  1281.       SF_SET_PROCESS (def_symbol_in_progress);    /* Will need processing before writing */
  1282.       /* intentional fallthrough */
  1283.     case C_FCN:
  1284.       {
  1285.     CONST char *name;
  1286.     S_SET_SEGMENT (def_symbol_in_progress, text_section);
  1287.  
  1288. #ifdef BFD_ASSEMBLER
  1289.     name = bfd_asymbol_name (def_symbol_in_progress->bsym);
  1290. #else
  1291.     name = def_symbol_in_progress->sy_symbol.ost_entry._n._n_nptr[1];
  1292. #endif
  1293.     if (name[1] == 'b' && name[2] == 'f')
  1294.       {
  1295.         if (function_lineoff < 0)
  1296.           as_warn ("`%s' symbol without preceding function", name);
  1297. #ifdef BFD_ASSEMBLER
  1298.         abort ();
  1299. #else
  1300.         SA_GET_SYM_LNNOPTR (def_symbol_in_progress) = function_lineoff;
  1301. #endif
  1302.         /* Will need relocating */
  1303.         SF_SET_PROCESS (def_symbol_in_progress);
  1304. #ifdef BFD_ASSEMBLER
  1305.         function_lineoff = 0;
  1306. #else
  1307.         function_lineoff = -1;
  1308. #endif
  1309.       }
  1310.       }
  1311.       break;
  1312.  
  1313. #ifdef C_AUTOARG
  1314.     case C_AUTOARG:
  1315. #endif /* C_AUTOARG */
  1316.     case C_AUTO:
  1317.     case C_REG:
  1318.     case C_MOS:
  1319.     case C_MOE:
  1320.     case C_MOU:
  1321.     case C_ARG:
  1322.     case C_REGPARM:
  1323.     case C_FIELD:
  1324.     case C_EOS:
  1325.       SF_SET_DEBUG (def_symbol_in_progress);
  1326.       S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
  1327.       break;
  1328.  
  1329.     case C_EXT:
  1330.     case C_STAT:
  1331.     case C_LABEL:
  1332.       /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
  1333.       break;
  1334.  
  1335.     case C_USTATIC:
  1336.     case C_EXTDEF:
  1337.     case C_ULABEL:
  1338.       as_warn ("unexpected storage class %d",
  1339.            S_GET_STORAGE_CLASS (def_symbol_in_progress));
  1340.       break;
  1341.     }                /* switch on storage class */
  1342.  
  1343.   /* Now that we have built a debug symbol, try to find if we should
  1344.      merge with an existing symbol or not.  If a symbol is C_EFCN or
  1345.      SEG_ABSOLUTE or untagged SEG_DEBUG it never merges. */
  1346.  
  1347.   /* Two cases for functions.  Either debug followed by definition or
  1348.      definition followed by debug.  For definition first, we will
  1349.      merge the debug symbol into the definition.  For debug first, the
  1350.      lineno entry MUST point to the definition function or else it
  1351.      will point off into space when obj_crawl_symbol_chain() merges
  1352.      the debug symbol into the real symbol.  Therefor, let's presume
  1353.      the debug symbol is a real function reference. */
  1354.  
  1355.   /* FIXME-SOON If for some reason the definition label/symbol is
  1356.      never seen, this will probably leave an undefined symbol at link
  1357.      time. */
  1358.  
  1359.   if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
  1360. #ifdef BFD_ASSEMBLER
  1361.       || (!strcmp (bfd_get_section_name (stdoutput,
  1362.                      S_GET_SEGMENT (def_symbol_in_progress)),
  1363.            "*DEBUG*")
  1364.       && !SF_GET_TAG (def_symbol_in_progress))
  1365. #else
  1366.       || (S_GET_SEGMENT (def_symbol_in_progress) == SEG_DEBUG
  1367.       && !SF_GET_TAG (def_symbol_in_progress))
  1368. #endif
  1369.       || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
  1370.       || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP)) == NULL)
  1371.     {
  1372. #ifdef BFD_ASSEMBLER
  1373.       if (def_symbol_in_progress != symbol_lastP)
  1374.     symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
  1375.                &symbol_lastP);
  1376. #else
  1377.       symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
  1378.              &symbol_lastP);
  1379. #endif
  1380.     }
  1381.   else
  1382.     {
  1383.       /* This symbol already exists, merge the newly created symbol
  1384.      into the old one.  This is not mandatory. The linker can
  1385.      handle duplicate symbols correctly. But I guess that it save
  1386.      a *lot* of space if the assembly file defines a lot of
  1387.      symbols. [loic] */
  1388.  
  1389.       /* The debug entry (def_symbol_in_progress) is merged into the
  1390.      previous definition. */
  1391.  
  1392.       c_symbol_merge (def_symbol_in_progress, symbolP);
  1393.       /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
  1394.       def_symbol_in_progress = symbolP;
  1395.  
  1396.       if (SF_GET_FUNCTION (def_symbol_in_progress)
  1397.       || SF_GET_TAG (def_symbol_in_progress))
  1398.     {
  1399.       /* For functions, and tags, the symbol *must* be where the
  1400.          debug symbol appears.  Move the existing symbol to the
  1401.          current place. */
  1402.       /* If it already is at the end of the symbol list, do nothing */
  1403.       if (def_symbol_in_progress != symbol_lastP)
  1404.         {
  1405.           symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
  1406.           symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
  1407.         }
  1408.     }
  1409.     }
  1410.  
  1411.   if (SF_GET_TAG (def_symbol_in_progress)
  1412.       && symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP) == NULL)
  1413.     {
  1414.       tag_insert (S_GET_NAME (def_symbol_in_progress), def_symbol_in_progress);
  1415.     }
  1416.  
  1417.   if (SF_GET_FUNCTION (def_symbol_in_progress))
  1418.     {
  1419.       know (sizeof (def_symbol_in_progress) <= sizeof (long));
  1420. #ifdef BFD_ASSEMBLER
  1421.       function_lineoff = def_symbol_in_progress;
  1422.       add_linesym (def_symbol_in_progress);
  1423. #else
  1424.       function_lineoff = c_line_new ((long) def_symbol_in_progress, 0,
  1425.                      &zero_address_frag);
  1426. #endif
  1427.       SF_SET_PROCESS (def_symbol_in_progress);
  1428.  
  1429.       if (symbolP == NULL)
  1430.     {
  1431.       /* That is, if this is the first time we've seen the
  1432.          function... */
  1433.       symbol_table_insert (def_symbol_in_progress);
  1434.     }            /* definition follows debug */
  1435.     }                /* Create the line number entry pointing to the function being defined */
  1436.  
  1437.   def_symbol_in_progress = NULL;
  1438.   demand_empty_rest_of_line ();
  1439.   return;
  1440. }
  1441.  
  1442. static void
  1443. obj_coff_dim ()
  1444. {
  1445.   register int dim_index;
  1446.  
  1447.   if (def_symbol_in_progress == NULL)
  1448.     {
  1449.       as_warn (".dim pseudo-op used outside of .def/.endef: ignored.");
  1450.       demand_empty_rest_of_line ();
  1451.       return;
  1452.     }                /* if not inside .def/.endef */
  1453.  
  1454.   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
  1455.  
  1456.   for (dim_index = 0; dim_index < DIMNUM; dim_index++)
  1457.     {
  1458.       SKIP_WHITESPACES ();
  1459.       SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index, get_absolute_expression ());
  1460.  
  1461.       switch (*input_line_pointer)
  1462.     {
  1463.  
  1464.     case ',':
  1465.       input_line_pointer++;
  1466.       break;
  1467.  
  1468.     default:
  1469.       as_warn ("badly formed .dim directive ignored");
  1470.       /* intentional fallthrough */
  1471.     case '\n':
  1472.     case ';':
  1473.       dim_index = DIMNUM;
  1474.       break;
  1475.     }            /* switch on following character */
  1476.     }                /* for each dimension */
  1477.  
  1478.   demand_empty_rest_of_line ();
  1479.   return;
  1480. }                /* obj_coff_dim() */
  1481.  
  1482. static void
  1483. obj_coff_line ()
  1484. {
  1485.   int this_base;
  1486.  
  1487.   if (def_symbol_in_progress == NULL)
  1488.     {
  1489.       obj_coff_ln ();
  1490.       return;
  1491.     }                /* if it looks like a stabs style line */
  1492.  
  1493.   this_base = get_absolute_expression ();
  1494.   if (this_base > line_base)
  1495.     {
  1496.       line_base = this_base;
  1497.     }
  1498.  
  1499.  
  1500.   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
  1501.   SA_SET_SYM_LNNO (def_symbol_in_progress, line_base);
  1502.  
  1503.   demand_empty_rest_of_line ();
  1504.   return;
  1505. }                /* obj_coff_line() */
  1506.  
  1507. static void
  1508. obj_coff_size ()
  1509. {
  1510.   if (def_symbol_in_progress == NULL)
  1511.     {
  1512.       as_warn (".size pseudo-op used outside of .def/.endef ignored.");
  1513.       demand_empty_rest_of_line ();
  1514.       return;
  1515.     }                /* if not inside .def/.endef */
  1516.  
  1517.   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
  1518.   SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
  1519.   demand_empty_rest_of_line ();
  1520.   return;
  1521. }                /* obj_coff_size() */
  1522.  
  1523. static void
  1524. obj_coff_scl ()
  1525. {
  1526.   if (def_symbol_in_progress == NULL)
  1527.     {
  1528.       as_warn (".scl pseudo-op used outside of .def/.endef ignored.");
  1529.       demand_empty_rest_of_line ();
  1530.       return;
  1531.     }                /* if not inside .def/.endef */
  1532.  
  1533.   S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
  1534.   demand_empty_rest_of_line ();
  1535.   return;
  1536. }                /* obj_coff_scl() */
  1537.  
  1538. static void
  1539. obj_coff_tag ()
  1540. {
  1541.   char *symbol_name;
  1542.   char name_end;
  1543.  
  1544.   if (def_symbol_in_progress == NULL)
  1545.     {
  1546.       as_warn (".tag pseudo-op used outside of .def/.endef ignored.");
  1547.       demand_empty_rest_of_line ();
  1548.       return;
  1549.     }                /* if not inside .def/.endef */
  1550.  
  1551.   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
  1552.   symbol_name = input_line_pointer;
  1553.   name_end = get_symbol_end ();
  1554.  
  1555.   /* Assume that the symbol referred to by .tag is always defined. */
  1556.   /* This was a bad assumption.  I've added find_or_make. xoxorich. */
  1557.   SA_SET_SYM_TAGNDX (def_symbol_in_progress,
  1558.              (long) tag_find_or_make (symbol_name));
  1559.   if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
  1560.     {
  1561.       as_warn ("tag not found for .tag %s", symbol_name);
  1562.     }                /* not defined */
  1563.  
  1564.   SF_SET_TAGGED (def_symbol_in_progress);
  1565.   *input_line_pointer = name_end;
  1566.  
  1567.   demand_empty_rest_of_line ();
  1568. }                /* obj_coff_tag() */
  1569.  
  1570. static void
  1571. obj_coff_type ()
  1572. {
  1573.   if (def_symbol_in_progress == NULL)
  1574.     {
  1575.       as_warn (".type pseudo-op used outside of .def/.endef ignored.");
  1576.       demand_empty_rest_of_line ();
  1577.       return;
  1578.     }                /* if not inside .def/.endef */
  1579.  
  1580.   S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
  1581.  
  1582.   if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
  1583.       S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
  1584.     {
  1585.       SF_SET_FUNCTION (def_symbol_in_progress);
  1586.     }                /* is a function */
  1587.  
  1588.   demand_empty_rest_of_line ();
  1589.   return;
  1590. }                /* obj_coff_type() */
  1591.  
  1592. static void
  1593. obj_coff_val ()
  1594. {
  1595.   if (def_symbol_in_progress == NULL)
  1596.     {
  1597.       as_warn (".val pseudo-op used outside of .def/.endef ignored.");
  1598.       demand_empty_rest_of_line ();
  1599.       return;
  1600.     }                /* if not inside .def/.endef */
  1601.  
  1602.   if (is_name_beginner (*input_line_pointer))
  1603.     {
  1604.       char *symbol_name = input_line_pointer;
  1605.       char name_end = get_symbol_end ();
  1606.  
  1607.       if (!strcmp (symbol_name, "."))
  1608.     {
  1609.       def_symbol_in_progress->sy_frag = frag_now;
  1610.       S_SET_VALUE (def_symbol_in_progress, obstack_next_free (&frags) - frag_now->fr_literal);
  1611.       /* If the .val is != from the .def (e.g. statics) */
  1612.     }
  1613.       else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
  1614.     {
  1615.       def_symbol_in_progress->sy_forward = symbol_find_or_make (symbol_name);
  1616.  
  1617.       /* If the segment is undefined when the forward
  1618.                reference is solved, then copy the segment id
  1619.                from the forward symbol. */
  1620.       SF_SET_GET_SEGMENT (def_symbol_in_progress);
  1621.     }
  1622.       /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
  1623.       *input_line_pointer = name_end;
  1624.     }
  1625.   else
  1626.     {
  1627.       S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ());
  1628.     }                /* if symbol based */
  1629.  
  1630.   demand_empty_rest_of_line ();
  1631.   return;
  1632. }                /* obj_coff_val() */
  1633.  
  1634. /*
  1635.  * Maintain a list of the tagnames of the structres.
  1636.  */
  1637.  
  1638. static void
  1639. tag_init ()
  1640. {
  1641.   tag_hash = hash_new ();
  1642.   return;
  1643. }                /* tag_init() */
  1644.  
  1645. static void
  1646. tag_insert (name, symbolP)
  1647.      CONST char *name;
  1648.      symbolS *symbolP;
  1649. {
  1650.   register char *error_string;
  1651.  
  1652.   if (*(error_string = hash_jam (tag_hash, name, (char *) symbolP)))
  1653.     {
  1654.       as_fatal ("Inserting \"%s\" into structure table failed: %s",
  1655.         name, error_string);
  1656.     }
  1657.   return;
  1658. }                /* tag_insert() */
  1659.  
  1660. static symbolS *
  1661. tag_find_or_make (name)
  1662.      char *name;
  1663. {
  1664.   symbolS *symbolP;
  1665.  
  1666.   if ((symbolP = tag_find (name)) == NULL)
  1667.     {
  1668.       symbolP = symbol_new (name, undefined_section,
  1669.                 0, &zero_address_frag);
  1670.  
  1671.       tag_insert (S_GET_NAME (symbolP), symbolP);
  1672.       symbol_table_insert (symbolP);
  1673.     }                /* not found */
  1674.  
  1675.   return (symbolP);
  1676. }                /* tag_find_or_make() */
  1677.  
  1678. static symbolS *
  1679. tag_find (name)
  1680.      char *name;
  1681. {
  1682. #ifdef STRIP_UNDERSCORE
  1683.   if (*name == '_')
  1684.     name++;
  1685. #endif /* STRIP_UNDERSCORE */
  1686.   return ((symbolS *) hash_find (tag_hash, name));
  1687. }                /* tag_find() */
  1688.  
  1689. void
  1690. obj_read_begin_hook ()
  1691. {
  1692.   /* These had better be the same.  Usually 18 bytes. */
  1693. #ifndef BFD_HEADERS
  1694.   know (sizeof (SYMENT) == sizeof (AUXENT));
  1695.   know (SYMESZ == AUXESZ);
  1696. #endif
  1697.   tag_init ();
  1698. }
  1699.  
  1700. void
  1701. obj_crawl_symbol_chain (headers)
  1702.      object_headers *headers;
  1703. {
  1704.   int symbol_number = 0;
  1705.   lineno *lineP;
  1706.   symbolS *last_functionP = NULL;
  1707.   symbolS *last_tagP;
  1708.   symbolS *symbolP;
  1709.   symbolS *symbol_externP = NULL;
  1710.   symbolS *symbol_extern_lastP = NULL;
  1711.  
  1712.   /* Initialize the stack used to keep track of the matching .bb .be */
  1713.   stack *block_stack = stack_init (512, sizeof (symbolS *));
  1714.  
  1715.   /* JF deal with forward references first... */
  1716.   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
  1717.     {
  1718.  
  1719.       if (symbolP->sy_forward)
  1720.     {
  1721.       S_SET_VALUE (symbolP, (S_GET_VALUE (symbolP)
  1722.                  + S_GET_VALUE (symbolP->sy_forward)
  1723.                    + symbolP->sy_forward->sy_frag->fr_address));
  1724.  
  1725.       if (
  1726. #ifndef TE_I386AIX
  1727.            SF_GET_GET_SEGMENT (symbolP)
  1728. #else
  1729.            SF_GET_GET_SEGMENT (symbolP)
  1730.            && S_GET_SEGMENT (symbolP) == SEG_UNKNOWN
  1731. #endif /* TE_I386AIX */
  1732.         )
  1733.         {
  1734.           S_SET_SEGMENT (symbolP, S_GET_SEGMENT (symbolP->sy_forward));
  1735.         }            /* forward segment also */
  1736.  
  1737.       symbolP->sy_forward = 0;
  1738.     }            /* if it has a forward reference */
  1739.     }                /* walk the symbol chain */
  1740.  
  1741.   tc_crawl_symbol_chain (headers);
  1742.  
  1743.   /* The symbol list should be ordered according to the following sequence
  1744.    * order :
  1745.    * . .file symbol
  1746.    * . debug entries for functions
  1747.    * . fake symbols for .text .data and .bss
  1748.    * . defined symbols
  1749.    * . undefined symbols
  1750.    * But this is not mandatory. The only important point is to put the
  1751.    * undefined symbols at the end of the list.
  1752.    */
  1753.  
  1754.   if (symbol_rootP == NULL
  1755.       || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
  1756.     {
  1757.       know (!previous_file_symbol);
  1758.       c_dot_file_symbol ("fake");
  1759.     }                /* Is there a .file symbol ? If not insert one at the beginning. */
  1760.  
  1761.   /*
  1762.    * Build up static symbols for .text, .data and .bss
  1763.    */
  1764.   dot_text_symbol = (symbolS *)
  1765.     c_section_symbol (".text",
  1766.               0,
  1767.               H_GET_TEXT_SIZE (headers),
  1768.               0 /*text_relocation_number */ ,
  1769.               0 /*text_lineno_number */ );
  1770. #ifdef TE_I386AIX
  1771.   symbol_remove (dot_text_symbol, &symbol_rootP, &symbol_lastP);
  1772.   symbol_append (dot_text_symbol, previous_file_symbol,
  1773.          &symbol_rootP, &symbol_lastP);
  1774. #endif /* TE_I386AIX */
  1775.  
  1776.   dot_data_symbol = (symbolS *)
  1777.     c_section_symbol (".data",
  1778.               H_GET_TEXT_SIZE (headers),
  1779.               H_GET_DATA_SIZE (headers),
  1780.               0 /*data_relocation_number */ ,
  1781.               0);    /* There are no data lineno entries */
  1782. #ifdef TE_I386AIX
  1783.   symbol_remove (dot_data_symbol, &symbol_rootP, &symbol_lastP);
  1784.   symbol_append (dot_data_symbol, dot_text_symbol,
  1785.          &symbol_rootP, &symbol_lastP);
  1786. #endif /* TE_I386AIX */
  1787.  
  1788.   dot_bss_symbol = (symbolS *)
  1789.     c_section_symbol (".bss",
  1790.               H_GET_TEXT_SIZE (headers) + H_GET_DATA_SIZE (headers),
  1791.               H_GET_BSS_SIZE (headers),
  1792.               0,    /* No relocation for a bss section. */
  1793.               0);    /* There are no bss lineno entries */
  1794. #ifdef TE_I386AIX
  1795.   symbol_remove (dot_bss_symbol, &symbol_rootP, &symbol_lastP);
  1796.   symbol_append (dot_bss_symbol, dot_data_symbol,
  1797.          &symbol_rootP, &symbol_lastP);
  1798. #endif /* TE_I386AIX */
  1799.  
  1800. #if defined(DEBUG)
  1801.   verify_symbol_chain (symbol_rootP, symbol_lastP);
  1802. #endif /* DEBUG */
  1803.  
  1804.   /* Three traversals of symbol chains here.  The
  1805.      first traversal yanks externals into a temporary
  1806.      chain, removing the externals from the global
  1807.      chain, numbers symbols, and does some other guck.
  1808.      The second traversal is on the temporary chain of
  1809.      externals and just appends them to the global
  1810.      chain again, numbering them as we go.  The third
  1811.      traversal patches pointers to symbols (using sym
  1812.      indexes).  The last traversal was once done as
  1813.      part of the first pass, but that fails when a
  1814.      reference preceeds a definition as the definition
  1815.      has no number at the time we process the
  1816.      reference. */
  1817.  
  1818.   /* Note that symbolP will be NULL at the end of a loop
  1819.      if an external was at the beginning of the list (it
  1820.      gets moved off the list).  Hence the weird check in
  1821.      the loop control.
  1822.      */
  1823.   for (symbolP = symbol_rootP;
  1824.        symbolP;
  1825.        symbolP = symbolP ? symbol_next (symbolP) : symbol_rootP)
  1826.     {
  1827.       if (!SF_GET_DEBUG (symbolP))
  1828.     {
  1829.       /* Debug symbols do not need all this rubbish */
  1830.       symbolS *real_symbolP;
  1831.  
  1832.       /* L* and C_EFCN symbols never merge. */
  1833.       if (!SF_GET_LOCAL (symbolP)
  1834.           && (real_symbolP = symbol_find_base (S_GET_NAME (symbolP), DO_NOT_STRIP))
  1835.           && real_symbolP != symbolP)
  1836.         {
  1837.           /* FIXME-SOON: where do dups come from?  Maybe tag references before definitions? xoxorich. */
  1838.           /* Move the debug data from the debug symbol to the
  1839.        real symbol. Do NOT do the oposite (i.e. move from
  1840.        real symbol to debug symbol and remove real symbol from the
  1841.        list.) Because some pointers refer to the real symbol
  1842.        whereas no pointers refer to the debug symbol. */
  1843.           c_symbol_merge (symbolP, real_symbolP);
  1844.           /* Replace the current symbol by the real one */
  1845.           /* The symbols will never be the last or the first
  1846.        because : 1st symbol is .file and 3 last symbols are
  1847.        .text, .data, .bss */
  1848.           symbol_remove (real_symbolP, &symbol_rootP, &symbol_lastP);
  1849.           symbol_insert (real_symbolP, symbolP, &symbol_rootP, &symbol_lastP);
  1850.           symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
  1851.           symbolP = real_symbolP;
  1852.         }            /* if not local but dup'd */
  1853.  
  1854.       if (flagseen['R'] && (S_GET_SEGMENT (symbolP) == SEG_DATA))
  1855.         {
  1856.           S_SET_SEGMENT (symbolP, SEG_TEXT);
  1857.         }            /* push data into text */
  1858.  
  1859.       S_SET_VALUE (symbolP, S_GET_VALUE (symbolP) + symbolP->sy_frag->fr_address);
  1860.  
  1861.       if (!S_IS_DEFINED (symbolP) && !SF_GET_LOCAL (symbolP))
  1862.         {
  1863.           S_SET_EXTERNAL (symbolP);
  1864.         }
  1865.       else if (S_GET_STORAGE_CLASS (symbolP) == C_NULL)
  1866.         {
  1867.           if (S_GET_SEGMENT (symbolP) == SEG_TEXT)
  1868.         {
  1869.           S_SET_STORAGE_CLASS (symbolP, C_LABEL);
  1870.         }
  1871.           else
  1872.         {
  1873.           S_SET_STORAGE_CLASS (symbolP, C_STAT);
  1874.         }
  1875.         }            /* no storage class yet */
  1876.  
  1877.       /* Mainly to speed up if not -g */
  1878.       if (SF_GET_PROCESS (symbolP))
  1879.         {
  1880.           /* Handle the nested blocks auxiliary info. */
  1881.           if (S_GET_STORAGE_CLASS (symbolP) == C_BLOCK)
  1882.         {
  1883.           if (!strcmp (S_GET_NAME (symbolP), ".bb"))
  1884.             stack_push (block_stack, (char *) &symbolP);
  1885.           else
  1886.             {        /* .eb */
  1887.               register symbolS *begin_symbolP;
  1888.               begin_symbolP = *(symbolS **) stack_pop (block_stack);
  1889.               if (begin_symbolP == (symbolS *) 0)
  1890.             as_warn ("mismatched .eb");
  1891.               else
  1892.             SA_SET_SYM_ENDNDX (begin_symbolP, symbol_number + 2);
  1893.             }
  1894.         }
  1895.           /* If we are able to identify the type of a function, and we
  1896.        are out of a function (last_functionP == 0) then, the
  1897.        function symbol will be associated with an auxiliary
  1898.        entry. */
  1899.           if (last_functionP == (symbolS *) 0 &&
  1900.           SF_GET_FUNCTION (symbolP))
  1901.         {
  1902.           last_functionP = symbolP;
  1903.  
  1904.           if (S_GET_NUMBER_AUXILIARY (symbolP) < 1)
  1905.             {
  1906.               S_SET_NUMBER_AUXILIARY (symbolP, 1);
  1907.             }        /* make it at least 1 */
  1908.  
  1909.           /* Clobber possible stale .dim information. */
  1910.           memset (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen,
  1911.               '\0', sizeof (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen));
  1912.         }
  1913.           /* The C_FCN doesn't need any additional information.
  1914.        I don't even know if this is needed for sdb. But the
  1915.        standard assembler generates it, so...
  1916.        */
  1917.           if (S_GET_STORAGE_CLASS (symbolP) == C_EFCN)
  1918.         {
  1919.           if (last_functionP == (symbolS *) 0)
  1920.             as_fatal ("C_EFCN symbol out of scope");
  1921.           SA_SET_SYM_FSIZE (last_functionP,
  1922.                     (long) (S_GET_VALUE (symbolP) -
  1923.                         S_GET_VALUE (last_functionP)));
  1924.           SA_SET_SYM_ENDNDX (last_functionP, symbol_number);
  1925.           last_functionP = (symbolS *) 0;
  1926.         }
  1927.         }
  1928.     }
  1929.       else if (SF_GET_TAG (symbolP))
  1930.     {
  1931.       /* First descriptor of a structure must point to
  1932.      the first slot after the structure description. */
  1933.       last_tagP = symbolP;
  1934.  
  1935.     }
  1936.       else if (S_GET_STORAGE_CLASS (symbolP) == C_EOS)
  1937.     {
  1938.       /* +2 take in account the current symbol */
  1939.       SA_SET_SYM_ENDNDX (last_tagP, symbol_number + 2);
  1940.     }
  1941.       else if (S_GET_STORAGE_CLASS (symbolP) == C_FILE)
  1942.     {
  1943.       if (symbolP->sy_symbol.ost_auxent->x_file.x_n.x_zeroes == 0)
  1944.       {
  1945.         symbolP->sy_symbol.ost_auxent->x_file.x_n.x_offset = string_byte_count;        
  1946.         string_byte_count +=
  1947.          strlen(GET_FILENAME_STRING(symbolP)) + 1;
  1948.  
  1949.  
  1950.       }
  1951.         
  1952.       if (S_GET_VALUE (symbolP))
  1953.         {
  1954.           S_SET_VALUE ((symbolS *) S_GET_VALUE (symbolP), symbol_number);
  1955.           S_SET_VALUE (symbolP, 0);
  1956.         }            /* no one points at the first .file symbol */
  1957.     }            /* if debug or tag or eos or file */
  1958.  
  1959.       /* We must put the external symbols apart. The loader
  1960.      does not bomb if we do not. But the references in
  1961.      the endndx field for a .bb symbol are not corrected
  1962.      if an external symbol is removed between .bb and .be.
  1963.      I.e in the following case :
  1964.      [20] .bb endndx = 22
  1965.      [21] foo external
  1966.      [22] .be
  1967.      ld will move the symbol 21 to the end of the list but
  1968.      endndx will still be 22 instead of 21. */
  1969.  
  1970.       if (SF_GET_LOCAL (symbolP))
  1971.     {
  1972.       /* remove C_EFCN and LOCAL (L...) symbols */
  1973.       /* next pointer remains valid */
  1974.       symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
  1975.  
  1976.     }
  1977.       else if (
  1978. #ifdef TE_I386AIX
  1979.            S_GET_STORAGE_CLASS (symbolP) == C_EXT
  1980.            && !SF_GET_FUNCTION (symbolP)
  1981. #else /* not TE_I386AIX */
  1982.            !S_IS_DEFINED (symbolP)
  1983.            && !S_IS_DEBUG (symbolP)
  1984.            && !SF_GET_STATICS (symbolP)
  1985. #endif /* not TE_I386AIX */
  1986.            )
  1987.     {
  1988.       /* if external, Remove from the list */
  1989.       symbolS *hold = symbol_previous (symbolP);
  1990.  
  1991.       symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
  1992.       symbol_clear_list_pointers (symbolP);
  1993.       symbol_append (symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP);
  1994.       symbolP = hold;
  1995.     }
  1996.       else
  1997.     {
  1998.       if (SF_GET_STRING (symbolP))
  1999.         {
  2000.           symbolP->sy_name_offset = string_byte_count;
  2001.           string_byte_count += strlen (S_GET_NAME (symbolP)) + 1;
  2002.         }
  2003.       else
  2004.         {
  2005.           symbolP->sy_name_offset = 0;
  2006.         }            /* fix "long" names */
  2007.  
  2008.       symbolP->sy_number = symbol_number;
  2009.       symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP);
  2010.     }            /* if local symbol */
  2011.     }                /* traverse the symbol list */
  2012.  
  2013.   for (symbolP = symbol_externP; symbol_externP;)
  2014.     {
  2015.       symbolS *tmp = symbol_externP;
  2016.  
  2017.       /* append */
  2018.       symbol_remove (tmp, &symbol_externP, &symbol_extern_lastP);
  2019.       symbol_append (tmp, symbol_lastP, &symbol_rootP, &symbol_lastP);
  2020.  
  2021.       /* and process */
  2022.       if (SF_GET_STRING (tmp))
  2023.     {
  2024.       tmp->sy_name_offset = string_byte_count;
  2025.       string_byte_count += strlen (S_GET_NAME (tmp)) + 1;
  2026.     }
  2027.       else
  2028.     {
  2029.       tmp->sy_name_offset = 0;
  2030.     }            /* fix "long" names */
  2031.  
  2032.       tmp->sy_number = symbol_number;
  2033.       symbol_number += 1 + S_GET_NUMBER_AUXILIARY (tmp);
  2034.     }                /* append the entire extern chain */
  2035.  
  2036.   /* When a tag reference preceeds the tag definition, the definition
  2037.      will not have a number at the time we process the reference
  2038.      during the first traversal.  Thus, a second traversal. */
  2039.  
  2040.   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
  2041.     {
  2042.       if (SF_GET_TAGGED (symbolP))
  2043.     {
  2044.       SA_SET_SYM_TAGNDX (symbolP, ((symbolS *) SA_GET_SYM_TAGNDX (symbolP))->sy_number);
  2045.     }
  2046.     }
  2047.  
  2048.   know (symbol_externP == NULL);
  2049.   know (symbol_extern_lastP == NULL);
  2050.  
  2051.   /* FIXME-SOMEDAY I'm counting line no's here so we know what to put
  2052.      in the section headers, and I'm resolving the addresses since I'm
  2053.      not sure how to do it later. I am NOT resolving the linno's
  2054.      representing functions.  Their symbols need a fileptr pointing to
  2055.      this linno when emitted.  Thus, I resolve them on emit.
  2056.      xoxorich. */
  2057.  
  2058.   for (lineP = lineno_rootP; lineP; lineP = lineP->next)
  2059.     {
  2060.       if (lineP->line.l_lnno > 0)
  2061.     {
  2062.       lineP->line.l_addr.l_paddr += ((fragS *) lineP->frag)->fr_address;
  2063.     }
  2064.       else
  2065.     {
  2066.       ;
  2067.     }
  2068.       text_lineno_number++;
  2069.     }                /* for each line number */
  2070.  
  2071.   H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number);
  2072.  
  2073.   return;
  2074. }
  2075.  
  2076. /*
  2077.  * Find strings by crawling along symbol table chain.
  2078.  */
  2079.  
  2080. void
  2081. obj_emit_strings (where)
  2082.      char **where;
  2083. {
  2084.   symbolS *symbolP;
  2085.  
  2086. #ifdef CROSS_COMPILE
  2087.   /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
  2088.   md_number_to_chars (*where, string_byte_count, sizeof (string_byte_count));
  2089.   *where += sizeof (string_byte_count);
  2090. #else /* CROSS_COMPILE */
  2091.   append (where, (char *) &string_byte_count, (unsigned long) sizeof (string_byte_count));
  2092. #endif /* CROSS_COMPILE */
  2093.  
  2094.   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
  2095.     {
  2096.       if (S_GET_STORAGE_CLASS(symbolP) == C_FILE) 
  2097.       {
  2098.     /* May need special treatment for this auxent */
  2099.     if (symbolP->sy_symbol.ost_auxent->x_file.x_n.x_zeroes == 0)
  2100.     {
  2101.       char *p = GET_FILENAME_STRING(symbolP);
  2102.       append 
  2103.        (where,p, strlen(p)+1);
  2104.     }
  2105.       }
  2106.       if (SF_GET_STRING (symbolP))
  2107.     {
  2108.       append (where, S_GET_NAME (symbolP),
  2109.           (unsigned long) (strlen (S_GET_NAME (symbolP)) + 1));
  2110.     }            /* if it has a string */
  2111.     }                /* walk the symbol chain */
  2112. }
  2113.  
  2114. void
  2115. obj_pre_write_hook (headers)
  2116.      object_headers *headers;
  2117. {
  2118.   register int text_relocation_number = 0;
  2119.   register int data_relocation_number = 0;
  2120.   register fixS *fixP;
  2121.  
  2122.   /* FIXME-SOMEDAY this should be done at fixup_segment time but I'm
  2123.      going to wait until I do multiple segments.  xoxorich. */
  2124.   /* Count the number of relocation entries for text and data */
  2125.   for (fixP = text_fix_root; fixP; fixP = fixP->fx_next)
  2126.     {
  2127.       if (fixP->fx_addsy)
  2128.     {
  2129.       ++text_relocation_number;
  2130. #ifdef TC_I960
  2131.       /* two relocs per callj under coff. */
  2132.       if (fixP->fx_callj)
  2133.         {
  2134.           ++text_relocation_number;
  2135.         }            /* if callj and not already fixed. */
  2136. #endif /* TC_I960 */
  2137. #ifdef TC_A29K
  2138.       /* Count 2 for a constH */
  2139.       if (fixP->fx_r_type == RELOC_CONSTH)
  2140.         {
  2141.           ++text_relocation_number;
  2142.         }
  2143. #endif
  2144.  
  2145.     }            /* if not yet fixed */
  2146.     }                /* for each fix */
  2147.  
  2148.   SA_SET_SCN_NRELOC (dot_text_symbol, text_relocation_number);
  2149.   /* Assign the number of line number entries for the text section */
  2150.   SA_SET_SCN_NLINNO (dot_text_symbol, text_lineno_number);
  2151.   /* Assign the size of the section */
  2152.   SA_SET_SCN_SCNLEN (dot_text_symbol, H_GET_TEXT_SIZE (headers));
  2153.  
  2154.   for (fixP = data_fix_root; fixP; fixP = fixP->fx_next)
  2155.     {
  2156.       if (fixP->fx_addsy)
  2157.     {
  2158.       ++data_relocation_number;
  2159.     }            /* if still relocatable */
  2160. #ifdef TC_A29K
  2161.       /* Count 2 for a constH */
  2162.       if (fixP->fx_r_type == RELOC_CONSTH)
  2163.     {
  2164.       ++data_relocation_number;
  2165.     }
  2166. #endif
  2167.  
  2168.     }                /* for each fix */
  2169.  
  2170.  
  2171.   SA_SET_SCN_NRELOC (dot_data_symbol, data_relocation_number);
  2172.   /* Assign the size of the section */
  2173.   SA_SET_SCN_SCNLEN (dot_data_symbol, H_GET_DATA_SIZE (headers));
  2174.  
  2175.   /* Assign the size of the section */
  2176.   SA_SET_SCN_SCNLEN (dot_bss_symbol, H_GET_BSS_SIZE (headers));
  2177.  
  2178.   /* pre write hook can add relocs (for 960 and 29k coff) so */
  2179.   headers->relocation_size = text_relocation_number * RELSZ +
  2180.     data_relocation_number * RELSZ;
  2181.  
  2182.  
  2183.  
  2184.   /* Fill in extra coff fields */
  2185.  
  2186.   /* Initialize general line number information. */
  2187.   H_SET_LINENO_SIZE (headers, text_lineno_number * LINESZ);
  2188.  
  2189.   /* filehdr */
  2190.   H_SET_FILE_MAGIC_NUMBER (headers, FILE_HEADER_MAGIC);
  2191.   H_SET_NUMBER_OF_SECTIONS (headers, 3);    /* text+data+bss */
  2192. #ifndef OBJ_COFF_OMIT_TIMESTAMP
  2193.   H_SET_TIME_STAMP (headers, (long) time ((long *) 0));
  2194. #else /* OBJ_COFF_OMIT_TIMESTAMP */
  2195.   H_SET_TIME_STAMP (headers, 0);
  2196. #endif /* OBJ_COFF_OMIT_TIMESTAMP */
  2197.   H_SET_SYMBOL_TABLE_POINTER (headers, H_GET_SYMBOL_TABLE_FILE_OFFSET (headers));
  2198. #if 0
  2199.   printf ("FILHSZ %x\n", FILHSZ);
  2200.   printf ("OBJ_COFF_AOUTHDRSZ %x\n", OBJ_COFF_AOUTHDRSZ);
  2201.   printf ("section headers %x\n", H_GET_NUMBER_OF_SECTIONS (headers) * SCNHSZ);
  2202.   printf ("get text size %x\n", H_GET_TEXT_SIZE (headers));
  2203.   printf ("get data size %x\n", H_GET_DATA_SIZE (headers));
  2204.   printf ("get relocation size %x\n", H_GET_RELOCATION_SIZE (headers));
  2205.   printf ("get lineno size %x\n", H_GET_LINENO_SIZE (headers));
  2206. #endif
  2207.   /* symbol table size allready set */
  2208.   H_SET_SIZEOF_OPTIONAL_HEADER (headers, OBJ_COFF_AOUTHDRSZ);
  2209.  
  2210.   /* do not added the F_RELFLG for the standard COFF.
  2211.      * The AIX linker complain on file with relocation info striped flag.
  2212.      */
  2213. #ifdef KEEP_RELOC_INFO
  2214.   H_SET_FLAGS (headers, (text_lineno_number == 0 ? F_LNNO : 0)
  2215.            | BYTE_ORDERING);
  2216. #else
  2217.   H_SET_FLAGS (headers, (text_lineno_number == 0 ? F_LNNO : 0)
  2218.     | ((text_relocation_number + data_relocation_number) ? 0 : F_RELFLG)
  2219.            | BYTE_ORDERING);
  2220. #endif
  2221.   /* aouthdr */
  2222.   /* magic number allready set */
  2223.   H_SET_VERSION_STAMP (headers, 0);
  2224.   /* Text, data, bss size; entry point; text_start and data_start are already set */
  2225.  
  2226.   /* Build section headers */
  2227.  
  2228.   c_section_header (&text_section_header,
  2229.             ".text",
  2230.             0,
  2231.             H_GET_TEXT_SIZE (headers),
  2232.             H_GET_TEXT_FILE_OFFSET (headers),
  2233.             (SA_GET_SCN_NRELOC (dot_text_symbol)
  2234.              ? H_GET_RELOCATION_FILE_OFFSET (headers)
  2235.              : 0),
  2236.             (text_lineno_number
  2237.              ? H_GET_LINENO_FILE_OFFSET (headers)
  2238.              : 0),
  2239.             SA_GET_SCN_NRELOC (dot_text_symbol),
  2240.             text_lineno_number,
  2241.             section_alignment[(int) SEG_TEXT]);
  2242.  
  2243.   c_section_header (&data_section_header,
  2244.             ".data",
  2245.             H_GET_TEXT_SIZE (headers),
  2246.             H_GET_DATA_SIZE (headers),
  2247.             (H_GET_DATA_SIZE (headers)
  2248.              ? H_GET_DATA_FILE_OFFSET (headers)
  2249.              : 0),
  2250.             (SA_GET_SCN_NRELOC (dot_data_symbol)
  2251.              ? (H_GET_RELOCATION_FILE_OFFSET (headers)
  2252.             + text_section_header.s_nreloc * RELSZ)
  2253.              : 0),
  2254.             0,        /* No line number information */
  2255.             SA_GET_SCN_NRELOC (dot_data_symbol),
  2256.             0,        /* No line number information */
  2257.             section_alignment[(int) SEG_DATA]);
  2258.  
  2259.   c_section_header (&bss_section_header,
  2260.             ".bss",
  2261.             H_GET_TEXT_SIZE (headers) + H_GET_DATA_SIZE (headers),
  2262.             H_GET_BSS_SIZE (headers),
  2263.             0,        /* No file offset */
  2264.             0,        /* No relocation information */
  2265.             0,        /* No line number information */
  2266.             0,        /* No relocation information */
  2267.             0,        /* No line number information */
  2268.             section_alignment[(int) SEG_BSS]);
  2269. }
  2270.  
  2271. /* This is a copy from aout.  All I do is neglect to actually build the symbol. */
  2272.  
  2273. static void
  2274. obj_coff_stab (what)
  2275.      int what;
  2276. {
  2277.   char *string;
  2278.   expressionS e;
  2279.   int goof = 0;            /* TRUE if we have aborted. */
  2280.   int length;
  2281.   int saved_type = 0;
  2282.   long longint;
  2283.   symbolS *symbolP = 0;
  2284.  
  2285.   if (what == 's')
  2286.     {
  2287.       string = demand_copy_C_string (&length);
  2288.       SKIP_WHITESPACE ();
  2289.  
  2290.       if (*input_line_pointer == ',')
  2291.     {
  2292.       input_line_pointer++;
  2293.     }
  2294.       else
  2295.     {
  2296.       as_bad ("I need a comma after symbol's name");
  2297.       goof = 1;
  2298.     }            /* better be a comma */
  2299.     }                /* skip the string */
  2300.  
  2301.   /*
  2302.      * Input_line_pointer->after ','.  String->symbol name.
  2303.      */
  2304.   if (!goof)
  2305.     {
  2306.       if (get_absolute_expression_and_terminator (&longint) != ',')
  2307.     {
  2308.       as_bad ("I want a comma after the n_type expression");
  2309.       goof = 1;
  2310.       input_line_pointer--;    /* Backup over a non-',' char. */
  2311.     }            /* on error */
  2312.     }                /* no error */
  2313.  
  2314.   if (!goof)
  2315.     {
  2316.       if (get_absolute_expression_and_terminator (&longint) != ',')
  2317.     {
  2318.       as_bad ("I want a comma after the n_other expression");
  2319.       goof = 1;
  2320.       input_line_pointer--;    /* Backup over a non-',' char. */
  2321.     }            /* on error */
  2322.     }                /* no error */
  2323.  
  2324.   if (!goof)
  2325.     {
  2326.       get_absolute_expression ();
  2327.  
  2328.       if (what == 's' || what == 'n')
  2329.     {
  2330.       if (*input_line_pointer != ',')
  2331.         {
  2332.           as_bad ("I want a comma after the n_desc expression");
  2333.           goof = 1;
  2334.         }
  2335.       else
  2336.         {
  2337.           input_line_pointer++;
  2338.         }            /* on goof */
  2339.     }            /* not stabd */
  2340.     }                /* no error */
  2341.  
  2342.   expression (&e);
  2343.  
  2344.   if (goof)
  2345.     {
  2346.       ignore_rest_of_line ();
  2347.     }
  2348.   else
  2349.     {
  2350.       demand_empty_rest_of_line ();
  2351.     }                /* on error */
  2352. }                /* obj_coff_stab() */
  2353.  
  2354. #ifdef BFD_ASSEMBLER
  2355. static
  2356. unsigned long
  2357. align (val, exp)
  2358. {
  2359.   int n = (1 << exp) - 1;
  2360.   printf ("align (%x, %x)\n", val, exp);
  2361.   val = (val + n) & ~n;
  2362.   return val;
  2363. }
  2364.  
  2365. void
  2366. coff_check_file_symbols (symp, punt)
  2367.      symbolS *symp;
  2368.      int *punt;
  2369. {
  2370.   static symbolS *last_functionP, *last_tagP;
  2371.   static stack *block_stack;
  2372.  
  2373.   if (!block_stack)
  2374.     block_stack = stack_init (512, sizeof (symbolS*));
  2375.  
  2376. #if 1
  2377.   if (!S_IS_DEFINED (symp) && S_GET_STORAGE_CLASS (symp) != C_STAT)
  2378.     S_SET_STORAGE_CLASS (symp, C_EXT);
  2379. #endif
  2380.  
  2381.   if (!SF_GET_DEBUG (symp))
  2382.     {
  2383.       symbolS *real;
  2384.       if (!SF_GET_LOCAL (symp)
  2385.       && (real = symbol_find_base (S_GET_NAME (symp), DO_NOT_STRIP))
  2386.       && real != symp)
  2387.     {
  2388.       c_symbol_merge (symp, real);
  2389.       *punt = 1;
  2390.     }
  2391.       if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
  2392.     {
  2393.       assert (S_GET_VALUE (symp) == 0);
  2394.       S_SET_EXTERNAL (symp);
  2395.     }
  2396.       else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
  2397.     {
  2398.       if (S_GET_SEGMENT (symp) == text_section)
  2399.         S_SET_STORAGE_CLASS (symp, C_LABEL);
  2400.       else
  2401.         S_SET_STORAGE_CLASS (symp, C_STAT);
  2402.     }
  2403.       if (SF_GET_PROCESS (symp))
  2404.     {
  2405.       if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
  2406.         {
  2407.           if (!strcmp (S_GET_NAME (symp), ".bb"))
  2408.         stack_push (block_stack, (char *) &symp);
  2409.           else
  2410.         {
  2411.           symbolS *begin;
  2412.           begin = *(symbolS **) stack_pop (block_stack);
  2413.           if (begin == 0)
  2414.             as_warn ("mismatched .eb");
  2415.           else
  2416.             SA_SET_SYM_ENDNDX (begin, begin);
  2417.         }
  2418.         }
  2419.       if (last_functionP == 0 && SF_GET_FUNCTION (symp))
  2420.         {
  2421.           union internal_auxent *auxp;
  2422.           last_functionP = symp;
  2423.           if (S_GET_NUMBER_AUXILIARY (symp) < 1)
  2424.         S_SET_NUMBER_AUXILIARY (symp, 1);
  2425.           auxp = &coffsymbol (symp->bsym)->native[1].u.auxent;
  2426.           memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
  2427.               sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
  2428.         }
  2429.       if (S_GET_STORAGE_CLASS (symp) == C_EFCN)
  2430.         {
  2431.           if (last_functionP == 0)
  2432.         as_fatal ("C_EFCN symbol out of scope");
  2433.           SA_SET_SYM_FSIZE (last_functionP,
  2434.                 (long) (S_GET_VALUE (symp)
  2435.                     - S_GET_VALUE (last_functionP)));
  2436.           SA_SET_SYM_ENDNDX (last_functionP, symp);
  2437.           last_functionP = 0;
  2438.         }
  2439.     }
  2440.       else if (SF_GET_TAG (symp))
  2441.     last_tagP = symp;
  2442.       else if (S_GET_STORAGE_CLASS (symp) == C_EOS)
  2443.     SA_SET_SYM_ENDNDX (last_tagP, symp);
  2444.       else if (S_GET_STORAGE_CLASS (symp) == C_FILE)
  2445.     {
  2446.       if (S_GET_VALUE (symp))
  2447.         {
  2448.           S_SET_VALUE ((symbolS *) S_GET_VALUE (symp), 0xdeadbeef);
  2449.           S_SET_VALUE (symp, 0);
  2450.         }
  2451.     }
  2452.       if (SF_GET_LOCAL (symp))
  2453.     *punt = 1;
  2454.       /* more ... */
  2455.     }
  2456.   if (coffsymbol (symp->bsym)->lineno)
  2457.     {
  2458.       int i, n;
  2459.       struct line_no *lptr;
  2460.       alent *l;
  2461.  
  2462.       lptr = (struct line_no *) coffsymbol (symp->bsym)->lineno;
  2463.       for (i = 0; lptr; lptr = lptr->next)
  2464.     i++;
  2465.       n = i + 1;
  2466.       lptr = (struct line_no *) coffsymbol (symp->bsym)->lineno;
  2467.       l = (alent *) bfd_alloc_by_size_t (stdoutput, n * sizeof (alent));
  2468.       coffsymbol (symp->bsym)->lineno = l;
  2469.       for (i = n - 1; i > 0; i--)
  2470.     {
  2471.       if (lptr->frag)
  2472.         lptr->l.u.offset += lptr->frag->fr_address;
  2473.       l[i] = lptr->l;
  2474.       lptr = lptr->next;
  2475.     }
  2476.     }
  2477. }
  2478.  
  2479. void 
  2480. DEFUN_VOID(obj_coff_section)
  2481. {
  2482.   /* Strip out the section name */
  2483.   char *section_name ;
  2484.   char *section_name_end;
  2485.   char c;
  2486.  
  2487.   unsigned int len;
  2488.   unsigned int exp;
  2489.  
  2490.   section_name =  input_line_pointer;
  2491.   c =   get_symbol_end();
  2492.   section_name_end =  input_line_pointer;
  2493.  
  2494.   len = section_name_end - section_name ;
  2495.   input_line_pointer++;
  2496.   SKIP_WHITESPACE();
  2497.   if (c == ',')
  2498.     exp = get_absolute_expression();
  2499.   else if (*input_line_pointer == ',')
  2500.     {
  2501.       input_line_pointer++;
  2502.       exp = get_absolute_expression();
  2503.     }
  2504.   else
  2505.     {
  2506.       exp = 0;
  2507.     }
  2508.  
  2509.   printf ("change_to_section(`%s',%d,%x)\n", section_name, len,exp);
  2510.   *section_name_end = c;
  2511. }
  2512.  
  2513. void
  2514. coff_frob_file ()
  2515. {
  2516.   if (symbol_rootP == NULL
  2517.       || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
  2518.     {
  2519.       assert (previous_file_symbol == 0);
  2520.       c_dot_file_symbol ("fake");
  2521.     }
  2522.   if (current_lineno_sym)
  2523.     add_linesym ((symbolS *) 0);
  2524. }
  2525. #endif /* BFD_ASSEMBLER */
  2526.  
  2527. #ifdef DEBUG
  2528. /* for debugging */
  2529. CONST char *
  2530. s_get_name (s)
  2531.      symbolS *s;
  2532. {
  2533.   return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
  2534. }                /* s_get_name() */
  2535.  
  2536. void
  2537. symbol_dump ()
  2538. {
  2539.   symbolS *symbolP;
  2540.  
  2541.   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
  2542.     {
  2543. #ifdef BFD_ASSEMBLER
  2544.       printf("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n",
  2545.          (unsigned long) symbolP,
  2546.          S_GET_NAME(symbolP),
  2547.          (long) S_GET_DATA_TYPE(symbolP),
  2548.          S_GET_STORAGE_CLASS(symbolP),
  2549.          (int) S_GET_SEGMENT(symbolP));
  2550. #else
  2551.       printf ("%3ld: 0x%lx \"%s\" type = %ld, class = %d, segment = %d\n",
  2552.           symbolP->sy_number,
  2553.           (unsigned long) symbolP,
  2554.           S_GET_NAME (symbolP),
  2555.           (long) S_GET_DATA_TYPE (symbolP),
  2556.           S_GET_STORAGE_CLASS (symbolP),
  2557.           (int) S_GET_SEGMENT (symbolP));
  2558. #endif
  2559.     }
  2560. }
  2561.  
  2562. #endif /* DEBUG */
  2563.  
  2564. /* end of obj-coff.c */
  2565.